答案 0 :(得分:18)
简而言之,您可以使用ember-route-action-helper插件。
<button {{action (route-action 'onButtonClick')}}>ClickToCallRouteAction</button>
有三种行动方式沟通,
<强> 1。旧式经典函数样式即,将函数名称从上到下传递为字符串。在我们需要定义相同功能和提供的所有地方。使用sendAction
冒泡。和send
方法从控制器到路由层次结构。
不鼓励这样做。 示例经典样式actions twiddle
<强> 2。关闭行动
使用action
辅助传递函数而不仅仅是字符串。这样你就不需要在任何地方定义它。
sample twiddle for closure actions样式
第3。 route-action-helper addon 强>
您只需使用route-action
帮助程序包装函数,就可以直接从任何地方直接调用路径操作。
Classic样式和Closure样式之间的比较以及为什么Closure是可取的?
onclick=(action (mut title) value="titlevalue")
(action 'save' target=session)
会查看actions
对象上的session
哈希,而不是当前上下文。 关于此的一些有前途的文章,
- miguelcamba文章ember-closure-actions-in-depth
- emberigniter文章send-closure-actions-up-data-owner
- emberjs博客1.13 release article
- 造船厂 - ember-best-practice-stop-bubbling-and-use-closure-actions
- 来自Ember地图的博客Why action helper?
- 来自Alisdair McDiarmid的博客ember-closure-actions-have-return-values
- 来自alexdiliberto的博客ember-closure-actions
答案 1 :(得分:2)
从Ember 3.14,Octane开始,我们可以以现代,明确,简洁和清晰的方式解决此问题-在短暂的间歇后,我们将解决这个问题:
我需要从子组件向主路线发送事件
尽管这是可能,但强烈建议您不要这样做,因为Routes不应有操作且应为无状态。也就是说,我们可以通过以下两种方式解决通过深层组件进行操作的问题:
首先,“数据关闭”,“操作增加”可以根据需要将参数向下传递到尽可能多的组件层
// app/controllers/application.js:
@action
dance(){
console.log('┏(-_-)┓┏(-_-)┛┗(-_- )┓')
}
// app/templates/application.hbs
<Foo @dance={{this.dance}} />
// app/components/foo.hbs
<Bar @dance={{@dance}} />
// app/components/bar.hbs
<button {{on 'click' @dance}}>Dance!</button>
这可能是一个滑坡。虽然只有两个组件可以记录数据并进行操作备份(在这种情况下单击之后),但似乎并不需要付出太多的努力,但是许多UI可能包含10多个组件,并且会采用一种称为Prop-Drilling的反模式。
为减轻 prop-drilling 的麻烦,我们在工具箱中提供了另一种方法。服务!
// app/services/my-service.js
@action
dance(){
console.log('┏(-_-)┓┏(-_-)┛┗(-_- )┓')
}
// app/components/bar.js
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
export default class Bar extends Component {
@service myService;
}
// app/components/bar.hbs
<button {{on 'click' this.myService.dance}}>Dance!</button>
深层嵌套的组件可以直接访问操作,而无需经过几层传递-这导致更易于维护和清晰的代码。
资源