将嵌套组件的操作传播到AppController

时间:2014-12-28 19:37:11

标签: ember.js

我有一个组件在其他组件中嵌套了几个级别。我试图将一个动作一直传播到AppController以便打开一个模态。

我知道这样做的唯一方法是将操作传递给每个组件 - 但这似乎非常不切实际。有没有更好的方法从嵌套组件访问AppController

See my jsbin for the code

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return ['red', 'yellow', 'blue'];
  }
});

App.AppController = Ember.Controller.extend({
    actions: {
        openModal: function(){
            alert('this would open the modal')
        }
    }
})

App.MainComponentComponent = Ember.Component.extend({})

App.SubComponentComponent = Ember.Component.extend({
    actions: {
        triggerModal: function(){
            // need to trigger the openModal action on the AppController
            this.sendAction('openModal')

        }
    }
})

<script type="text/x-handlebars" data-template-name="index">
  <h1>Index</h1>

{{main-component model=model}}
</script>

<script type="text/x-handlebars" data-template-name="components/main-component">
  <h2>Main component</h2>

{{#each color in model}}
    {{sub-component color=color}}
{{/each}}
</script>   

<script type="text/x-handlebars" data-template-name="components/sub-component">
  <button {{action "triggerModal"}}>{{color}}</button>
</script>

编辑:我知道我可以将模板渲染到模态插座中:

this.render(modalName, {
  into: 'application',
  outlet: 'modal'
});

但我正在尝试访问AppController上的操作。

2 个答案:

答案 0 :(得分:2)

您可以使用Ember.Instrumentation module,可以像pub / sub一样使用。
这是a working JS Bin example

解决方案大纲:
1.在ApplicationController init,控制器订阅"openModal"事件 2. neseted组件用于处理事件"openModal"中的事件 3.仪器可以使用有效载荷执行,因此这将是确定模态内容的地方。

App.ApplicationController = Ember.Controller.extend({
  actions: {
    openModal: function(options) {
      alert('this would open the modal with the content: ' + options.modalContent);
    }
  },
  subscribeEvents: function() {
    this.set('openModalSubscriber', Ember.Instrumentation.subscribe('openModal', {
      before: Ember.K,
      after: Ember.run.bind(this, function(name, timestamp, payload, beforeRet) {
        this.send('openModal', payload);
      }),
    }, this));
  }.on('init')
});
App.SubComponentComponent = Ember.Component.extend({
  actions: {
    triggerModal: function() {
      Ember.Instrumentation.instrument('openModal.sub-component', {
        modalContent: 'Inner content of modal'
      }, Ember.K, this);
    }
  }
});

答案 1 :(得分:0)

组件应该是相当孤立的,因此跳过其他组件,直接进入他们的控制器可能没有意义......请参阅以下讨论here

有一个targetObject属性,可能对你有用,虽然我不是100%肯定你会在这种情况下设置它。