在另一个隔离范围指令中共享指令中的数据

Share data from a directive within another isolated scope directive

我正在尝试通过编写组件样式指令对我的 Angular 代码采用组件方法,但我遇到了 运行 问题。下面是我的 html 页面模板。请注意,我使用的是 AngularStrap tabs 指令。

我遇到的问题是 woSamplesSummary.materialsCount 在 work-order 指令下未定义(在选项卡窗格范围之外),但它在选项卡窗格指令中正确显示为一部分选项卡标题(在选项卡窗格范围内)。所以基本问题是在另一个独立范围指令中使用指令时如何在页面上共享数据?

<work-order wo-id="{{woId}}"></work-order>
<div>Materials Count: {{woSamplesSummary.materialsCount}}</div>

<!--- TABS ------>
<div ng-show="woId" bs-tabs>

    <!--- MATERIALS --->
    <div bs-pane title="Materials ({{woSamplesSummary.materialsCount}})" id="materials">

        <work-order-samples 
            wo-id="{{woId}}" 
            wo-samples-summary="woSamplesSummary" >
        </work-order-samples>
    </div>

    <!--- additional tabs not shown --->

</div>

这是我的 work-order-samples 指令。我删除了大部分逻辑,但您可以看到我使用 two-way 绑定设置了 woSamplesSummary 并将属性绑定到控制器,这一切都正常工作并且允许我不再使用 $scope.

.directive('workOrderSamples', function () {
    return {
        restrict: 'E',
        replace: 'false',
        templateUrl: 'myTemplate',
        scope: { },
        controllerAs: 'wosamplesCtlr',
        bindToController: {
            woId: '@',
            woSamplesSummary: '='
        },
        controller: function ($scope, $element, $attrs, myModel) {
            var self = this;
            $attrs.$observe('woId', function(woId) {
                workOrderSamples.find(conditions).then(function () {
                    self.woSamples          = workOrderSamples;
                    self.woSamplesSummary   = {
                        batchCount: workOrderSamples.batches.length,
                        materialsCount: workOrderSamples.list.length }
                });
            });
        }
    };
})

所以问题似乎是 tabs 指令正在创建一个独立的范围,所以我无法在我所在的选项卡之外提供数据。

当在其他独立范围指令中使用指令时,似乎应该有一种方法可以使指令中的数据可用。我尝试了很多不同的方法,但都没有成功。在我的指令中将值分配给 $rootScope 确实有效,但这不是一个好的解决方案(例如 - 如果我想在页面上多次使用该指令)。

有什么想法吗?

Angular有两种交流方式。其中之一是使用服务。另一种是使用$broadcast和$emit/$on.

Angular 使用 $broadcast、$emit、$on 的自定义事件。

在你的指令中,我将从以下内容开始:

$rootScope.$broadcast('myEvent', data)

然后在接收端:

$rootScope.$on('myEvent', function(e, args){
   // do stuff
});

您还必须取消注册 $rootScope 侦听器以避免内存泄漏。你这样做的方法是调用 $on returns 的函数并在作用域的 $destroy 事件期间应用它。

var cleanfunction = $rootScope.$on('showLogin', showLoginDialog());

$scope.$on('$destroy', function(){
  cleanfunction();
})