Ember 组件发送动作到路由
Posted
技术标签:
【中文标题】Ember 组件发送动作到路由【英文标题】:Ember component send action to route 【发布时间】:2017-07-06 20:13:08 【问题描述】:我有两个组件,一个坐在另一个组件上。我需要从子组件向主路由发送事件(两个组件在同一路由中使用)
请告诉我是否有任何标准方法可以做到这一点。
【问题讨论】:
【参考方案1】:从 Ember 3.14 开始,Octane,我们可以用一种现代、明确、简洁和清晰的方式解决这个问题——我们将在这个短暂的中场休息后开始:
我需要从子组件向主路由发送事件
虽然这是可能,但强烈建议不要这样做,因为路由不应该有动作并且应该是无状态的。也就是说,我们可以通过以下几种方式解决动作通过深层组件的问题:
"Data Down, Actions Up" 使用服务对于第一个,Data Down,Actions Up,您可以根据需要将参数向下传递任意多个组件层
// 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>
这可能是一个滑坡。虽然只有两个组件来记录数据和 action 备份(在这种情况下单击后),但这似乎并不费力,但许多 UI 可能有 10 多个组件深度,并且将适用于称为 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>
深层嵌套的组件可以直接访问动作,而不需要经过几层传递——这会导致代码更易于维护和更清晰。
资源
Classic to Octane Cheat Sheet Octane Edition Documentation Page【讨论】:
!remindme 2 天:查看代码和框是否已修复,并提供实时工作代码示例 虽然这显示了一个很好的模式,但它根本没有回答这个问题。我在试图弄清楚如何在路由上调用内置动作(刷新)时偶然发现了这一点,如果试图避免添加控制器 + 额外动作 + 使用sendAction
只是为了这个目的。似乎是路由服务缺少的功能。【参考方案2】:
对于简短的回答,您可以使用ember-route-action-helper 插件。
<button action (route-action 'onButtonClick')>ClickToCallRouteAction</button>
共有三种action通信方式,
1.旧式经典函数样式 即,将函数名称作为字符串从上到下传递。并且在所有地方我们需要定义相同的功能并提供。使用sendAction
冒泡。和 send
从控制器到路由层次结构的方法冒泡。
不鼓励这样做。 经典风格样张actions twiddle
2。关闭操作
使用action
辅助传递函数,而不仅仅是字符串。这样您就不需要在任何地方定义它。
sample twiddle for closure actions风格
3. route-action-helper addon
只需使用 route-action
助手包装函数,您就可以从任何地方直接调用路由操作。
Sample twiddle
Classic 风格与 Closure 风格的比较以及为什么 Closure 更可取?
在经典风格中,您需要在每个级别定义动作并使用 sendAction 触发每个级别的动作,直到您完全摆脱嵌套。 您可以在关闭操作中返回值,但不能在经典操作中返回。 您可以在闭包操作中使用 curry 值,但不能在经典操作中使用。 如果找不到操作,关闭操作会立即失败。但是经典的动作设计,只会在调用时懒惰地引发错误 价值观。 编码复杂性,例如谁来处理操作和执行业务逻辑? 在闭包中,您可以结合 action 和 mut helper 来设置具有值的属性。onclick=(action (mut title) value="titlevalue")
在闭包中,您可以指定目标对象来调用函数。 (action 'save' target=session)
将查看session
对象上的actions
哈希,而不是当前上下文。
一些关于此的有希望的文章, - miguelcamba 文章ember-closure-actions-in-depth - 引燃文章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
【讨论】:
为什么不鼓励old style classic functions style?您能否详细说明(1)和(2)之间的区别。 @LiXinyang 更新了差异以及为什么首选闭包以及一些好文章。 感谢您抽出宝贵时间@kumkanillam。点赞! +10 所有这些参考都很棒 爱你@kumkanillam 这个关闭动作节省了我的一天,可能还有很多小时的研究如何做到这一点。 很好的答案,谢谢@kumkanillam。参考文献很棒,谢谢。如果可以的话,我会投票 x10。以上是关于Ember 组件发送动作到路由的主要内容,如果未能解决你的问题,请参考以下文章
Ember.js:从嵌套路由调用 ApplicationRoute 的操作