从控制器调用组件上的函数

时间:2017-06-23 16:04:13

标签: ember.js

我喜欢你对这种模式的看法。我希望能够从我的控制器上调用一个组件上的焦点函数,我实现它的方式是通过控制器上定义的操作引用它自己,然后调用它上面的方法。它工作正常只是想知道我应该远离某种反模式吗?

{{x-input bindingAction=(action "bindInput")}}

<button {{action "focusOnInput">Focus on input</button>

 // x-input.js
import Ember from 'ember';

export default Ember.Component.extend({

  init() {
    this._super();
    if (!Ember.isNone(this.get('bindingAction')) {
     this.get('bindingAction')(this)
    }   
  }

  focus() {
    // focus on component.
  }

});


// controller.js
import Ember from 'ember';

export default Ember.Controller.extend({

actions: {

    bindInput(input) {
       this.set('input', input);    
    }

    focusOnInput() {
       this.get('input').focus();       
    }

}
});

1 个答案:

答案 0 :(得分:1)

是。从控制器调用组件上的函数是反模式。始终遵循Data Down和Actions Up策略。 必须将数据传递给组件,组件应通过发送操作来传达更改。

下面的一些文章要更好地理解,
- https://emberigniter.com/getting-started-ember-cli-data-down-actions-up-tutorial/
- https://dockyard.com/blog/2015/10/14/best-practices-data-down-actions-up
- http://www.samselikoff.com/blog/data-down-actions-up/
- https://blog.embermap.com/passing-data-around-your-ember-application-c4fe1e06e90

如果您仍想这样做,那么我会选择这个选项, 这是twiddle demonstrating

控制器/ application.js中

import Ember from 'ember';
export default Ember.Controller.extend({
  appName: 'Ember Twiddle',
  componentRef:null,
  actions:{
    registerComponent(componentRef){
      this.set('componentRef',componentRef);
    },
    deregisterComponent(){
      this.set('componentRef',null);
    },
    callComponentMethod(){
        this.get('componentRef').sayHi();
      }
  }
});

组件/我的-component.js

import Ember from 'ember';
export default Ember.Component.extend({
  didInsertElement(){
    this.get('registerComponent')(this);
  },
  willDestroyElement(){
    this.get('deregisterComponent')();
    this._super(...argument);    
  },
  sayHi(){
   alert(' Hi from component');
  }

});

application.hbs

<h1 {{action 'callComponentMethod'}}>Welcome to {{appName}}</h1>
<br>
{{my-component registerComponent=(action 'registerComponent') deregisterComponent=(action 'deregisterComponent')}}
{{outlet}}