本文介绍了在另一个隔离范围指令中共享来自指令的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

<工单样本wo-id="{{woId}}"wo-samples-summary="woSamplesSummary" ></work-order-samples>

<!--- 其他选项卡未显示--->

这是我的工作订单样品指令.我删除了大部分逻辑,但您可以看到我使用双向绑定设置了 woSamplesSummary 并将属性绑定到控制器,这一切正常,并且让我不再使用 $scope.

.directive('workOrderSamples', function () {返回 {限制:'E',替换:'假',templateUrl: 'myTemplate',范围: { },controllerAs: 'wosamplesCtlr',绑定到控制器:{woId: '@',woSamplesSummary: '='},控制器:函数($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,材料数量:workOrderSamples.list.length }});});}};})

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

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

有什么想法吗?

解决方案

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

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

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

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

然后在接收端:

$rootScope.$on('myEvent', function(e, args){//做东西});

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

var cleanfunction = $rootScope.$on('showLogin', showLoginDialog());$scope.$on('$destroy', function(){清洁功能();})

I'm trying to take a component approach to my Angular code by writing component style directives, but I have run into a problem. Below is my html template for the page. Note that I'm using the AngularStrap tabs directive.

The problem I'm having is that the woSamplesSummary.materialsCount is undefined right under the work-order directive (outside of the tab pane scope), but it displays correctly in the tab pane directive as part of the tab title (within the tab pane scope). So the basic issue is how to share data on a page when using a directive within another isolated scope directive?

<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>

Here's my work-order-samples directive. I removed most of the logic, but you can see that I setup woSamplesSummary with two-way binding and have bound the properties to the controller, which is all working correctly and has allowed me to move away from using $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 }
                });
            });
        }
    };
})

So the problem seems to be that the tabs directive is creating an isolated scope, so I am not able to make the data available outside of the tab I'm in.

It seems like there should be a way to make data available from a directive when it's used within other isolated scope directives. I've tried many different approaches, but without any success. Assigning the value to $rootScope within my directive does work, but it's just not a good solution (e.g. - if I want to use this directive multiple times on a page).

Any ideas?

解决方案

There are two ways of communication in Angular. One of which is to use services. The other is to use $broadcast and $emit/$on.

Angular Custom Events using $broadcast, $emit, $on.

In your directive I'd start with:

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

Then on the receiving end:

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

You must also unregister $rootScope listeners to avoid memory leaks. The way you do that is by calling the function that the $on returns and apply it during the scope's $destroy event.

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

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

这篇关于在另一个隔离范围指令中共享来自指令的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 15:10