如何从控制器调用组件的方法 [英] How to call method of a component from a controller

查看:84
本文介绍了如何从控制器调用组件的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代表地图的组件,并且在我的控制器中的一个动作之后,我想调用该组件上的一个方法来集中地图。代码看起来像这样

  App.PlacesController = Ember.Controller.extend({
actions:{
centerMap:function(){
//如何从这里调用到GoogleMapComponent.centerMap?
}
}
});


App.GoogleMapComponent = Ember.Component.extend({
centerMap:function(){
}
});

模板

  {{google-map}} 
< button {{actioncenterMap}}> Center Map< / button>

我找到了一个解决方法,但我不认为这是Ember的做法。 / p>

  {{google-map viewName =mapView}} 
< button class =center-map> ;中心地图< / button>

App.PlacesView = Ember.View.extend({
didInsertElement:function(){
this。$(。center-map)。click(this.clickCenterMap .bind(this));
},

clickCenterMap:function(){
this.get(mapView)。centerMap();
}
});


解决方案

在Ember中,视图(组件是荣耀的视图)知道关于他们的控制器,但控制器不了解视图。这是通过设计(MVC)来保持事物的分离,因此您可以拥有许多由单个控制器动力的视图,而控制器不是更明智的。所以当考虑关系时,控制器会发生变化,视图会对这些变化做出反应。所以,只是重申一下,你不应该试图从一个控制器中访问一个视图/组件。



在处理你的例子时,我可以想到几个选项。


  1. 将组件的按钮组成部分!组件旨在处理用户输入,如按钮点击,因此您可能需要考虑将按钮作为地图组件的一部分,并处理组件操作哈希中的点击。如果这个按钮总是伴随地图组件,那么我当然推荐这种方法。


  2. 你可以在你的控制器上有一个布尔属性,如 isCentered ,当按钮被点击时,它设置为true。在您的组件中,您可以绑定到该控件的属性,并在该属性更改时做出反应。这是一个双向绑定,所以如果用户移动地图,您也可以将您的本地绑定属性更改为false。



    控制器:

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

    组件: p>

      ... 
    isCenteredBinding:'controller.isCentered',
    onIsCenteredChange:function(){
    //做你的东西
    } .observes('isCentered'),
    ...


  3. 如果将Ember.Evented mixin混合到控制器中,Jeremy Green的解决方案可以工作(它添加了pub / sub 触发器方法)



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

App.PlacesController = Ember.Controller.extend({
  actions : {
    centerMap : function () {
        // how to call from here to GoogleMapComponent.centerMap ??
    }
  }
});


App.GoogleMapComponent = Ember.Component.extend({
  centerMap : function () {
  }
});

template

{{google-map}}
<button {{action "centerMap"}}>Center Map</button>

I have found a workaround but I don't think this is the Ember way of doing this.

{{google-map viewName="mapView"}}
<button class="center-map">Center Map</button>

App.PlacesView = Ember.View.extend({
  didInsertElement : function () {
    this.$(".center-map").click(this.clickCenterMap.bind(this));
  },

  clickCenterMap : function () {
    this.get("mapView").centerMap();
  }
});

解决方案

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)

这篇关于如何从控制器调用组件的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆