在另一个隔离范围指令

时间:2015-11-02 20:51:35

标签: angularjs angularjs-directive angularjs-scope isolate-scope

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

我遇到的问题是woSamplesSummary.materialsCount在工作订单指令下(在选项卡窗格范围之外)未定义,但它在选项卡窗格指令中正确显示为选项卡标题的一部分(在标签窗格范围)。因此,基本问题是如何在另一个隔离范围指令中使用指令时在页面上共享数据?

<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指令。我删除了大部分逻辑,但你可以看到我设置了带双向绑定的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确实有效,但它不是一个好的解决方案(例如 - 如果我想在页面上多次使用此指令)。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

Angular有两种沟通方式。其中之一是使用服务。另一种是使用$ broadcast和$ emit / $。

使用$ broadcast,$ emit,$ on。

的Angular自定义事件

在你的指令中,我从:

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

然后在接收端:

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

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

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

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