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



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

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

请参阅我的 jsbin 以获取代码

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上的操作.

您可以使用 Ember.Instrumentation 模块,它可以像发布/订阅一样使用。
这是一个有效的 JS Bin 示例。

解决方案概要:
1. 在 ApplicationController init 时,控制器订阅"openModal"事件。
2. 内衬组件检测操作中的事件"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);
    }
  }
});

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

有一个targetObject属性,可能对您有用,尽管我不是 100% 确定在这种情况下您会将其设置为什么。

最新更新