路由

时间:2017-02-17 10:32:07

标签: ember.js

我有两个组件,一个坐在另一个组件上。我需要从子组件向主路径发送一个事件(两个组件在相同路径中使用)

enter image description here

请告诉我有没有标准方法可以做到。

2 个答案:

答案 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帮助程序包装函数,就可以直接从任何地方直接调用路径操作。

Sample twiddle

Classic样式和Closure样式之间的比较以及为什么Closure是可取的?

  • 在经典风格中,您需要在每个级别定义操作,并使用sendAction在每个级别触发操作,直到您完全退出嵌套。
  • 您可以在关闭操作中返回值,但不能在经典操作中返回值。
  • 您可以在关闭操作中调整值,但不能在经典操作中调整值。
  • 如果未找到操作,则关闭操作会立即失败。但是设计上的经典动作只会在调用时懒惰地引发错误 值。
  • 编码复杂性,比如谁将处理操作并执行业务逻辑?
  • 在闭包中,您可以组合action和mut helper来设置具有值的属性。 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>  

深层嵌套的组件可以直接访问操作,而无需经过几层传递-这导致更易于维护和清晰的代码。

资源