[自定义指令]放置范围之间的区别。$ watch on link vs scope。$ watch on controller

时间:2021-03-27 13:32:13

Sorry if this has been answered but I can't find a documentation that satisfy myself.

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

What's the difference between using the scope.$watch on the link vs the controller function in the custom directive?

使用范围有什么区别。链接上的$ 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) {
        });
    }

My application behaves exactly the same putting logic in both places. Any idea?

我的应用程序在两个地方都表现出完全相同的推送逻辑。任何想法?

2 个解决方案

#1


1  

There is no difference, other than it being in a different place.

除了在不同的地方之外没有区别。

#2


1  

Functionally there is no difference between the two - either way you're adding a watcher to the scope (if it acted differently then there would be a problem!).

从功能上来说,两者之间没有区别 - 无论是你将观察者添加到范围内(如果它采取不同的行动,那么就会出现问题!)。

I tend to add watchers in the directive to control how external attributes are mapped to internal scope variables (similar to the directive isolate scope). i.e. the controller doesn't care where the values come from, as long as they are on the scope.

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

I then use watchers in the controller to watch values on those internal properties - to know when sub-properties have changed and respond to that inside the controller. i.e. the directive doesn't care about how the properties are used, it just needs to put them on the scope for the controller.

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

Here is an example using isolate scope:

以下是使用隔离范围的示例:

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

Here is an example using a child scope but mapping the same external value to scope.internalProp. This doesn't create an isolate scope so you still get scope inheritance (which can be useful sometimes).

下面是使用子范围但将相同外部值映射到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.
            });
        }
    };
});

In both examples it's the directive that controls how external attributes are mapped to internal scope properties and then the controller can work with those internal properties as-needed.

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

#1


1  

There is no difference, other than it being in a different place.

除了在不同的地方之外没有区别。

#2


1  

Functionally there is no difference between the two - either way you're adding a watcher to the scope (if it acted differently then there would be a problem!).

从功能上来说,两者之间没有区别 - 无论是你将观察者添加到范围内(如果它采取不同的行动,那么就会出现问题!)。

I tend to add watchers in the directive to control how external attributes are mapped to internal scope variables (similar to the directive isolate scope). i.e. the controller doesn't care where the values come from, as long as they are on the scope.

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

I then use watchers in the controller to watch values on those internal properties - to know when sub-properties have changed and respond to that inside the controller. i.e. the directive doesn't care about how the properties are used, it just needs to put them on the scope for the controller.

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

Here is an example using isolate scope:

以下是使用隔离范围的示例:

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

Here is an example using a child scope but mapping the same external value to scope.internalProp. This doesn't create an isolate scope so you still get scope inheritance (which can be useful sometimes).

下面是使用子范围但将相同外部值映射到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.
            });
        }
    };
});

In both examples it's the directive that controls how external attributes are mapped to internal scope properties and then the controller can work with those internal properties as-needed.

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