Ember.js Ember组件调用路由或控制器中的操作

Ember.js Ember组件调用路由或控制器中的操作,ember.js,Ember.js,我有一个组件,其主要目的是显示一行项目。 每行都有一个删除按钮,可以删除一行。如何将动作从模板传递到将触发路由器中动作的组件 以下是使用组件的模板: #templates/holiday-hours.hbs {{#each model as |holidayHour|}} {{holiday-hour holiday=holidayHour shouldDisplayDeleteIcon=true}} {{/each}} 以下是组件模板: # templates/components/h

我有一个组件,其主要目的是显示一行项目。 每行都有一个删除按钮,可以删除一行。如何将动作从模板传递到将触发路由器中动作的组件

以下是使用组件的模板:

#templates/holiday-hours.hbs

{{#each model as |holidayHour|}}
  {{holiday-hour holiday=holidayHour shouldDisplayDeleteIcon=true}}
{{/each}}
以下是组件模板:

# templates/components/holiday-hour.hbs
...
div class="col-sm-1">
    {{#if shouldDisplayDeleteIcon}}
    <button type="button" class="btn btn-danger btn-sm mt-1" {{action 'deleteHoliday' holiday}}>
      <span class="oi oi-trash"></span>
    </button>
    {{/if}}
</div>
#模板/组件/holiday-hour.hbs
...
div class=“col-sm-1”>
{{#如果应该显示删除图标}
{{/if}
我正在使用相同的组件显示一行并创建一个新项目(
holiday hour

我正在使用余烬3.1.2


谢谢

您必须将操作从组件发送到路由。实现这一点的主要方法是向组件添加操作,将操作“发送”到父级。一旦动作被发送,您必须通过将动作作为参数传递给组件来告诉组件要在路由上触发什么动作。下面是一个如何做到这一点的例子

组件js

# components/holiday-hour.js
...
actions: {
   deleteHoliday(){
      this.sendAction('deleteHoliday');
   }
}
路线模板

#templates/holiday-hours.hbs
...
{{#each model as |holidayHour|}}
  {{holiday-hour holiday=holidayHour shouldDisplayDeleteIcon=true deleteHoliday='deleteHoliday'}}
{{/each}}
路线js

#routes/holiday-hours.js
...
actions: {
    deleteHoliday(){
        //code to delete holiday
    }
}

我将尝试给出一个一般性的答案,因为您的问题没有提供足够/所有关于路线行动等的信息。长答案短,使用闭包功能。假设这是您的route js文件
routes/holiday hours.js

import Route from '@ember/routing/route';

export default Route.extend({
    model(){ /*... some code */ },
    setupController(controller){
        this._super(controller);
        controller.set('actions', {
             passToComponent: function(param) { //.... function logic }
        })
    }
});
注意:在上面的代码片段中,我使用
setupController
创建操作。或者,您可以将操作放在控制器文件中,否则直接放在路由中的操作将抛出错误。 因此,我希望从组件调用动作
passToComponent
。这是使其在组件内部可访问的操作

{{#each model as |holidayHour|}}   {{holiday-hour holiday=holidayHour shouldDisplayDeleteIcon=true callAction=(action 'passToComponent')} {{/each}}
import Component from '@ember/component';

export default Component.extend({
    actions: {
       deleteHoliday: ()=> {
         this.get('callAction')() /*Pass in any params in the brackets*/
       }
    }
});
现在我们已经将操作传递给组件,下面是如何从组件调用它。注意:我添加了一个param只是为了表明在组件中调用时它可以接受一个param

{{#each model as |holidayHour|}}   {{holiday-hour holiday=holidayHour shouldDisplayDeleteIcon=true callAction=(action 'passToComponent')} {{/each}}
import Component from '@ember/component';

export default Component.extend({
    actions: {
       deleteHoliday: ()=> {
         this.get('callAction')() /*Pass in any params in the brackets*/
       }
    }
});

您还将看到使用
sendAction
的演示,这是一种非常古老的方法,其作用更像是一种效率不高的事件总线。阅读更多内容

非常感谢您如此清晰的解释(我将其放在余烬指南中)。尽管如此,似乎我必须将操作放入控制器:
断言失败:在中找不到名为“deleteHoliday”的操作,即使我定义了与路由中相同的操作
deleteHoliday
,也不会发生任何事:(.我同意操作必须在控制器中,或者在路线内使用
setupController
。这是一个I设置。我将更新我的答案以反映这一点。啊,我忘了在
模板/组件/假日时间中的
删除
按钮上放回以前删除的操作。hbs
。它工作了只有当我在
holiday hours.js
controller中定义了
delete holiday
操作时,我才可以这样做。我已经编辑了答案并添加了一条注释,该操作必须在controller中或路线的setupController中。正如@kimobrian254所说,请参阅解释
sendAction
使用优缺点。我知道这是两年前发布的但谢谢!非常清晰且有效的示例!@feedy这是一个相当古老的答案。它可能应该更新为使用关闭操作,因为这是现在更合适的方法。请参阅,它包含了更多解释清楚的文章。