25

マップを表すコンポーネントがあり、コントローラーでアクションを実行した後、コンポーネントのメソッドを呼び出してマップを中央に配置したいと考えています。コードは次のようになります

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


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

テンプレート

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

回避策を見つけましたが、これが Ember のやり方だとは思いません。

{{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();
  }
});
4

5 に答える 5

23

Ember では、ビュー (コンポーネントは美化されたビューです) はコントローラーを認識しますが、コントローラーはビューを認識しません。これは設計 (MVC) によるものであり、分離を維持するため、単一のコントローラーによって「駆動」されている多くのビューを使用できますが、コントローラーは賢明ではありません。したがって、関係について考えると、コントローラーに変更が発生する可能性があり、ビューはそれらの変更に反応します。したがって、繰り返しになりますが、コントローラー内からビュー/コンポーネントにアクセスしようとしないでください。

あなたの例を扱うときに私が考えることができるいくつかのオプションがあります。

  1. ボタンをコンポーネントの一部にしましょう! コンポーネントは、ボタンのクリックなどのユーザー入力を処理することを目的としているため、ボタンをマップ コンポーネントの一部にして、コンポーネントのアクション ハッシュでクリックを処理することを検討することをお勧めします。このボタンが常にマップ コンポーネントに付随する場合は、この方法をお勧めします。

  2. コントローラーに のようなブール値のプロパティを設定できisCentered、ボタンがクリックされると true に設定されます。コンポーネントでは、そのコントローラーのプロパティにバインドし、そのプロパティが変更されるたびに反応できます。これは双方向バインディングであるため、たとえばユーザーがマップを移動した場合は、ローカルにバインドされたプロパティを false に変更することもできます。

    コントローラ:

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

    成分:

    ...
    isCenteredBinding: 'controller.isCentered',
    onIsCenteredChange: function () {
        //do your thing
    }.observes('isCentered'),
    ...
    
  3. Ember.Evented ミックスインをコントローラーに混合すると、Jeremy Green のソリューションが機能します (これにより、pub/subtriggeronメソッドが追加されます) 。

于 2013-10-31T18:11:16.317 に答える
9

を使用onしてコンポーネントにコントローラーからのイベントをリッスンさせ、コントローラーで を使用triggerしてイベントを発行できます。

したがって、コンポーネントには次のようなものがあるかもしれません:

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

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

そして、あなたのコントローラーでは次のことができます:

actions : {
  centerMap : function () {
    this.trigger('recenter');
  }
}
于 2013-10-29T19:34:59.267 に答える
6

コンポーネント プロパティをテンプレートのコントローラ プロパティにバインドします。

    {{google-map componentProperty=controllerProperty}}

次に、コンポーネントのコンポーネント プロパティを確認します。

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

controllerPropertyこれで、コントローラーで変更されるたびonChangeに、コンポーネントで が呼び出されます。

この回答から、2番目の段落。

于 2015-03-04T23:19:18.440 に答える
1

コンポーネント呼び出しの内部:

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

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

于 2014-05-19T17:13:06.240 に答える