$ parent vs call在父子指令通信中的最佳方法

时间:2015-10-24 08:10:19

标签: angularjs angularjs-directive emit

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

意味着如果child指令需要以某种方式更新父指令(两者都有隔离的范围), 我是不是该  传递一个回调函数:

e.g:

.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():

e.g:

  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');
                };
            }
        };
    });

我觉得排放量会更容易理解,但担心性能和开销,但我仍然不确定

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

修改

我忘记了

  

需要

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

3 个答案:

答案 0 :(得分:1)

为此目的,最好是利用“require”属性。

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

  

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

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

我修改了你的例子,所以reusableDir可以调用filterReviewStepBox控制器,但也可以单独使用。

http://jsbin.com/gedaximeko/edit?html,js,console,output

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');
                  }
                };
            }
        };
    });

答案 1 :(得分:1)

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

除了我自己的个人观点,如果它是一种更具“未来发展”的方法,那么回调方法是迄今为止最安全的方法。这就是为什么......

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

然而,在AngularJS和Angular2中,仍然建议通过服务进行通信。

答案 2 :(得分:0)

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

  1. 回调方法:这可能是最有效的选择。 child指令只调用父指令的一个方法,no 开销。这里解释了不少选项: https://stackoverflow.com/a/27997722/2889528

  2. 发出(或就此而言广播):此方法将事件发布到所有$ scope(s)up(emit)或down(broadcast)到层次结构, 相对昂贵但它可以让您灵活地观察和处理 $ scope范围可用的事件。

  3. 可注入的公共服务:当您想要调用$ scope不可用的方法时,可以使用此选项。但是,它严重依赖服务。这更像是一个 pub-sub design。