【问题标题】:Ember component call an action in a route or controllerEmber 组件调用路由或控制器中的操作
【发布时间】:2018-05-03 15:34:18
【问题描述】:

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

这是使用该组件的模板:

#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)。

我正在使用 ember 3.1.2

谢谢

【问题讨论】:

  • 请参考my answer 它包含更多解释清楚的文章。

标签: ember.js


【解决方案1】:

您必须将动作从组件向上发送到路由。执行此操作的主要方法是向您的组件添加操作,将操作“发送”到父级。发送动作后,您必须通过将动作作为参数传递来告诉组件要触发路由上的什么动作。以下是如何执行此操作的示例。

组件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
    }
}

【讨论】:

  • 正如@kimobrian254 所说,请参阅this aticle 解释sendAction 使用利弊。
  • 我知道这是 2 年前发布的,但谢谢!非常清晰和有效的例子!
  • @feedy 这是一个相当古老的答案。它可能应该更新为使用关闭操作,因为这是现在更合适的方法。
【解决方案2】:

我会尝试给出一个一般性的答案,因为您的问题没有提供有关路线操作等的足够/所有信息。简短的回答,使用闭包函数。假设这是你的路由 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 }
        })
    }
});

注意:在上面的 sn-p 中,我使用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*/
       }
    }
});

您还将看到使用 sendAction 的演示,它相当陈旧,更像是一种效率不高的事件总线。阅读更多来自article

【讨论】:

  • 非常感谢您提供如此清晰的解释(我将其命名为 Ember 指南)。不过,似乎我必须将操作放入控制器中:Assertion Failed: An action named 'deleteHoliday' was not found in &lt;decastore-front@controller。我将以下内容放入templates/holiday-hours.hbs{{holiday-hour holiday=holidayHour shouldDisplayDeleteIcon=true deleteAction=(action 'deleteHoliday' holidayHour)}}。然后在components/holiday-hour.js:deleteHoliday(holiday) { this.get('deleteAction')(holiday); }.
  • 即使我在路由中定义了相同的操作deleteHoliday,也没有任何反应:(。
  • 我同意动作必须在控制器中,或者在路由中使用setupController。这是我设置的twiddle。我将更新我的答案以反映这一点。
  • 啊,我忘了把之前删除的操作放回templates/componenets/holiday-hour.hbs 中的delete 按钮上:&lt;button type="button" class="btn btn-danger btn-sm mt-1" {{action 'deleteHoliday' holiday}}&gt;。仅当我在 holiday-hours.js 控制器中定义了 deleteHoliday 操作时,它才有效。
  • 我已经编辑了答案并添加了注释,该操作必须在控制器中或路由中的 setupController 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
相关资源
最近更新 更多