8

我试图了解在具有隔离范围的父子指令之间进行通信的最佳通用方法是什么(它们可能是可重用的项目)。

意思是如果子指令需要以某种方式更新父指令(两者都有独立的范围),我应该传递一个回调函数:

例如:

.directive('filterReviewStepBox', function () {
    return {
        restrict: 'EA',
        scop: {
            //some data
        },
        template: '<div>text<reusable-dir></reusable-dir call-back="foo"></div>',
        link: function (scope, elem, attrs) {
            scope.foo = function () {
                console.log('bar');
            };
        }
    };
}).directive('reusableDir', function () {
    return {
        restrict: 'EA',
        scope: {
            callBack: '=callBack'
                //other data
        },
        template: '<div>text<button type="button" ng-click="bar"></button></div>',
        link: function (scope, elem, attrs) {
            scope.bar = function () {
                scope.callBack();
            }
        }
    };
});

或者我应该使用 $emit():

例如:

  directive('filterReviewStepBox', function () {
        return {
            restrict: 'EA',
            scope: {
                // some data
            },
            template: '<div>text<reusable-dir></reusable-dir></div>',
            link: function (scope, elem, attrs) {
                scope.$on('foo', function () {
                    console.log('bar');
                });
            }
        };
    }).directive('reusableDir', function () {
        return {
            restrict: 'EA',
            scope: { //some data
            },
            template: '<div>text<button type="button" ng-click="bar"></button></div>',
            link: function (scope, elem, attrs) {
                scope.bar = function () {
                    scope.$emit('foo');
                };
            }
        };
    });

我觉得在更大的范围内发射会更容易理解,但担心性能和开销,但我仍然不确定

尝试在网上寻找最好的方法,但我仍然跺着脚

编辑

我忘记了

要求

选项。但我仍然不确定这是最正确的解决方案。因为这不允许我重用孩子或孙子,并且有点使指令成为单一用途的项目。

4

3 回答 3

1

为此,最好使用“require”属性。

指令的完整指南告诉我们有关 require 属性的信息:https ://docs.angularjs.org/api/ng/service/ $compile

需要另一个指令并将其控制器作为第四个参数注入链接函数。require 接受要传入的指令的字符串名称(或字符串数​​组)。

Require 只是告诉指令它应该寻找一些父指令并获取它的控制器。您可以使用^前缀告诉指令在父元素中搜索,并使用 ? 判断此要求是否是可选的字首。

我已经修改了您的示例,因此 reusableDir 可以调用 filterReviewStepBox 控制器,但也可以单独使用。

http://jsbin.com/gedaximeko/edit?html,js,控制台,输出

angular.module('stackApp', [])  
.directive('filterReviewStepBox', function () {
        return {
            restrict: 'EA',
            scope: {
                // some data
            },
            template: '<div>text<reusable-dir></reusable-dir></div>',
            link: function (scope, elem, attrs) {

            },
            controller : function() {
              this.notify = function(value) {
                console.log('Notified : ' + value);
              };              
            },
            controllerAs: 'vm',
            bindToController: true
        };
    }).directive('reusableDir', function () {
        return {
            restrict: 'EA',
            scope: { //some data
            },
            require: '?^filterReviewStepBox',
            template: '<div>text<button type="button" ng-click="bar()"></button></div>',
            link: function (scope, elem, attrs, controller) {
                scope.bar = function () {
                  if (controller) {
                    controller.notify('foo');
                  }
                };
            }
        };
    });
于 2015-10-27T14:40:40.840 回答
1

就个人而言,我尽量避免生成自己的自定义事件。主要是因为它非常容易导致不需要的事件传播或冒泡(通常会导致不需要的范围摘要),而且还因为在更大的应用程序中可能变得非常难以管理的系统性“噪音”。

抛开我自己的个人观点不谈,如果您正在寻找一种更“面向未来”的方法,那么回调方法是迄今为止最安全的。这就是为什么...

  • Angular2 鼓励开发人员onChange从依赖于父子通信的指令和组件中公开属性。请注意,这些只不过是绑定函数,应在给定组件或指令的绑定或范围中相应地定义。
  • 与上面类似,Angular2 记录了一个ngOnChanges方法,可以由任何希望订阅对其绑定更改的控制器定义。$scope.$watch如果提供,此方法会在任何 DOM 操作发生之前调用(使用新的绑定值),因此它是当前 AngularJS实现中更“通用”的父子通信的完美候选者。

然而,没有提到的是,在 AngularJS 和 Angular2 中仍然建议通过服务进行通信。


于 2016-04-19T20:34:42.017 回答
0

我认为这不仅仅是关于性能,你还需要从设计和维护的角度考虑更多的因素。

  1. 回调方法:这可能是最有效的选择。子指令只会调用父指令的一种方法,没有开销。这里解释了很多选项: https ://stackoverflow.com/a/27997722/2889528

  2. 发射(或就此而言广播):此方法将事件发布到所有 $scope(s) 向上(发射)或向下(广播)到层次结构,相对昂贵,但它使您可以灵活地在 $scope 的任何地方观看和处理事件可用。

  3. Injectable Common Service:当您想调用 $scope 不可用的某些方法时,可以使用此选项。但是,它对服务产生了紧密的依赖。这更像是一种 pub-sub 设计。

于 2016-04-16T04:58:17.133 回答