角度组件模式通信

时间:2015-11-14 02:18:58

标签: angularjs

经过多次搜索,我仍然无法绕过某些东西。

假设我有一个视频播放器指令需要能够响应其他播放按钮指令,这些指令可能是也可能不是兄弟姐妹。 当我说回复时,我的意思是当点击播放按钮时,它可以告诉视频播放器指令播放视频。

仅供参考视频播放器不是html5视频播放器,它是一个jankaty iframe的东西需要一个jankaty postmessage api进行通信。 (那部分我已经想出了:)

<some-component>
video player in here somewhere
</some-component>

<play-button></play-button>
...
<play-button></play-button>

如何使用组件指令模式实现此目的。我试图在没有绑定指令的控制器中远离这种情况。

问题

是否有视频播放器指令侦听$ rootScope事件邪恶?人们似乎对此持不同意见。

这看起来像一个用例和一个相当规律的概念。(不是兄弟姐妹或需要沟通的孩子的组件)使用中间服务真的是唯一干净的方法吗?似乎拥有一个玩家服务只会因为它提供播放/暂停功能和跟踪状态而过度杀伤。

2 个答案:

答案 0 :(得分:1)

我认为这可能是一个好主意。我将去做ngForm指令所做的事情。 ngform伪指令接受一个名称,并将其控制器公开给父作用域上的该名称对象。

此方法适用于包装控制器或包装组件。 这是一个小例子。 http://plnkr.co/edit/3kvWKdckrW2cErRS9yIj?p=preview

<wrapping-component or ctrl>
  <player name="ctrl.player">
  </some-component>

  <play-button player="ctrl.player"></play-button>
  ...
  <play-button player="ctrl.player"></play-button>
</wrapping-component or ctrl>

警告:玩家指令最不可能是孤立范围。

编辑:

player指令可以是isolate scope指令。通过使用$ parse服务,您可以执行此操作。

var setter = $parse(ctrl.name).assign; //You could also use $scope.name, I'm using bindToController.
setter($scope.$parent, ctrl)//Sets the directive controller on the parent scope as the ctrl.name value

现在如果你有

<player name="player4"></player>

您现在可以在此父范围内稍后说明。

...ng-click="player4.play()"

答案 1 :(得分:0)

虽然您描述的这些组件是独立的,但至少有一个(控件)不能(或mabye不应该)没有另一个。

播放器控件显然属于播放器,并且在某种程度上应该在播放器和控件之间建立过度连接。如果您不想将数据存储在视图或更高阶的控制器中,那么我建议将播放器和控件嵌套在指令/组件本身中,这两者都可以访问该指令控制器。

那样责任仍然与整个“父”组件隔离开来。

您的问题的答案:

是否有视频播放器指令侦听$ rootScope事件邪恶?

邪恶,没有。仍然习惯于在全球范围内滥用活动,以便人们可以从应用中的任何位置进行访问?是。从代码维护的角度来看,像这样的事件监听器可能会变得很痛苦,因为您必须始终确保一起更新侦听器和发射器。当然这可能是微不足道的,但维护的代码越少越好。

使用中间服务真的是唯一干净的方法吗?

除了将两个组件包装在父组件中之外,最有可能。注入时的服务可以作为单独使用,并且只要注入就可以从任何指示访问。所以可以说这是合适的。它可能似乎像矫枉过正,但它将问题分开并允许代码模块化。