How to call method of a component from a controller

前端 未结 5 458
感情败类
感情败类 2020-12-14 01:35

I have a component that represent a map and after an action in my controller I want to call a method on the component to center the map. The code looks like this

<         


        
相关标签:
5条回答
  • 2020-12-14 02:12

    You can use on to have your component listen for an event from the controller, then you can use trigger in the controller to emit an event.

    So in your component you might have something like this:

    didInsertElement : function(){
      this.get('controller').on('recenter', $.proxy(this.recenter, this));
    },
    
    recenter : function(){
      this.get("mapView").centerMap()
    }
    

    And in your controller you could have :

    actions : {
      centerMap : function () {
        this.trigger('recenter');
      }
    }
    
    0 讨论(0)
  • 2020-12-14 02:13

    Bind a component property to the controller property in the template:

        {{google-map componentProperty=controllerProperty}}
    

    Then observe the component property in the component:

        onChange: function () {
            // Do your thing
        }.observes('componentProperty')
    

    Now every time controllerProperty is changed in the controller, onChange in the component will be called.

    From this answer, second paragraph.

    0 讨论(0)
  • 2020-12-14 02:20

    I think it's OK to have a reference in your controller to your component. It's true that your component encapsulates it's own behaviour, but public methods like reload etc. are perfectly fine.

    My solution for this is to pass the current controller to the component and set a property on the controller within the component.

    Example

    template.hbs:

    {{#component delegate=controller property="refComponent"}}

    component.js:

    init: function() {
       this._super.apply(this, arguments);
    
       if (this.get("delegate")) {
          this.get('delegate').set(this.get("property") || "default", this);
       }
    }
    

    Now in your controller you can simply get a reference to your component with this.get("refComponent").

    Steffen

    0 讨论(0)
  • 2020-12-14 02:22

    In Ember, views (Components are glorified views) know about their controller, but controllers do NOT know about views. This is by design (MVC) to keep things decoupled, and so you can have many views that are being "powered" by a single controller, and the controller is none the wiser. So when thinking about the relationship, changes can happen to a controller and a view will react to those changes. So, just to reiterate, you should never try to access a view/component from within a controller.

    There are a few options I can think of when dealing with your example.

    1. Make the button part of your component! Components are meant to handle user input, like button clicks, so you may want to consider making the button a part of the map component and handle clicks in the actions hash of your component. If this buttons is always going to accompany the map component, then I certainly recommend this approach.

    2. You could have a boolean property on your controller like isCentered, and when the button is clicked it's set to true. In your component you can bind to that controller's property, and react whenever that property changes. It's a two-way binding so you can also change your locally bound property to false if the user moves the map, for example.

      Controller:

      ...
      isCentered: false,
      actions: {
          centerMap: {
              this.set('isCentered', true);
          }
      }
      ...
      

      Component:

      ...
      isCenteredBinding: 'controller.isCentered',
      onIsCenteredChange: function () {
          //do your thing
      }.observes('isCentered'),
      ...
      
    3. Jeremy Green's solution can work if you mix in the Ember.Evented mixin into the controller (which adds the pub/sub trigger and on methods)

    0 讨论(0)
  • 2020-12-14 02:22

    Inside of your component call:

    var parentController = this.get('targetObject');
    

    See: http://emberjs.com/api/classes/Ember.Component.html#property_targetObject

    0 讨论(0)
提交回复
热议问题