【问题标题】:[Custom Directive]Difference between putting scope.$watch on link vs scope.$watch on controller[自定义指令]将 scope.$watch 放在链接上与 scope.$watch 放在控制器上的区别
【发布时间】:2024-01-22 08:45:02
【问题描述】:

很抱歉,如果这个问题已经得到解答,但我找不到让自己满意的文档。

在链接上使用 scope.$watch 与在自定义指令中使用控制器函数有什么区别?

var linker = function (scope, element) {

    // same watch block
    scope.$watch('propertyToWatch', function (value) {

    });

    element.html(template).show();
    $compile(element.contents())(scope);
};

return {
    require: '^directiveName',
    scope: {

    },
    link: linker,
    controller: ['$scope', function ($scope) {

        // same watch block
        scope.$watch('propertyToWatch', function (value) {
        });
    }

我的应用程序在两个地方的放置逻辑完全相同。有什么想法吗?

【问题讨论】:

    标签: javascript angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    没有区别,只是在不同的地方。

    【讨论】:

    • 我认为可能有一些与 $scope.$digest 或 $scope.$apply 相关的东西
    • 不,与此无关。
    【解决方案2】:

    从功能上讲,两者之间没有区别 - 无论哪种方式,您都在向作用域添加观察者(如果它的行为不同,那么就会有问题!)。

    我倾向于在指令中添加观察者来控制外部属性如何映射到内部范围变量(类似于指令隔离范围)。即控制器不关心值来自哪里,只要它们在范围内。

    然后我在控制器中使用观察器来观察这些内部属性的值 - 以了解子属性何时发生变化并在控制器内部做出响应。即指令不关心属性是如何使用的,它只需要将它们放在控制器的范围内。

    这里是一个使用隔离作用域的例子:

    angular.module('MyModule').directive('myDirective', function(){
        return {
            scope: {
                // The isolate scope sets up a watcher on the external
                // property and makes it available on the scope
                // as `scope.internalProp`
                'internalProp': '=externalProp'
            },
            controller: function($scope){
                // Work with `internalProp` - the directive
                // manages putting it on the scope.
                $scope.internalProp //...
    
                $scope.$watch('internalProp.myProp', function(value){
                    // Do something when `myProp` changes.
                });
            }
        };
    });
    

    这是一个使用子作用域但将相同的外部值映射到scope.internalProp 的示例。 这不会创建隔离范围,因此您仍然可以获得范围继承(有时可能很有用)。

    angular.module('MyModule').directive('myDirective', function($parse){
        return {
            scope: true,
            link: function(scope, element, attr){
                // Example of manually watching an attribute value
                // in a directive.
    
                var propGetter = $parse(attr['externalProp']);
                scope.$parent.$watch(propGetter, function(value){
                    scope.internalProp = value;
                });
            },
            controller: function($scope){
                // Work with `internalProp` - the directive
                // manages putting it on the scope.
                $scope.internalProp //...
    
                $scope.$watch('internalProp.myProp', function(value){
                    // Do something when `myProp` changes.
                });
            }
        };
    });
    

    在这两个示例中,它是控制外部属性如何映射到内部范围属性的指令,然后控制器可以根据需要使用这些内部属性。

    【讨论】: