一个指令=一个额外的观察程序



每个指令都有一个额外的观察程序吗?这是示例代码 - http://plnkr.co/edit/Mg4Z7PUUJI0dQRNfFZ8z?p=preview它有 4 个带有一次性绑定的自定义指令,但我有 5 个观察者,应该只有 1 个。为什么?

 angular.module("myApp", [])
            .controller("initCtrl", function ($scope, $interval) {
                $scope.dane = {
                    zm1: 'Directive 1 with onetime binding',
                    zm2: 'Directive 2 with onetime binding',
                    zm3: 'Directive 3 with onetime binding',
                    zm4: 'Directive 4 with onetime binding',
                };
                $interval(function () {
                    $scope.watchers = countWatchers();
                }, 1000);
            })
            .directive("myDir", function () {
                return {
                    scope: {
                        ngModel: "="
                    },
                    require: "ngModel",
                    link: function (scope, element, attrs, ctrl) {
                    },
                    template: "<div>{{::ngModel}}</div>"
                }
            })
    ;
    /**
     * Funkcja do zliczania watchers - max 2000
     */
    (function () {
        window.countWatchers = function () {
            var root = angular.element(document.getElementsByTagName('body'));
            var watchers = [];
            var f = function (element) {
                angular.forEach(['$scope', '$isolateScope'], function (scopeProperty) {
                    if (element.data() && element.data().hasOwnProperty(scopeProperty)) {
                        angular.forEach(element.data()[scopeProperty].$$watchers, function (watcher) {
                            watchers.push(watcher);
                        });
                    }
                });
                angular.forEach(element.children(), function (childElement) {
                    f(angular.element(childElement));
                });
            };
            f(root);
            // Remove duplicate watchers
            var watchersWithoutDuplicates = [];
            angular.forEach(watchers, function (item) {
                if (watchersWithoutDuplicates.indexOf(item) < 0) {
                    watchersWithoutDuplicates.push(item);
                }
            });
            return watchersWithoutDuplicates.length;
        };
    })();
<!DOCTYPE html>
<html>
  <head>
    <script data-require="angular.js@1.3.6" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body data-ng-app="myApp">
<div ng-controller="initCtrl" class="container">
    <div class="well">Watchers: {{watchers}}</div>
    <my-dir ng-model="::dane.zm1"></my-dir>
    <my-dir ng-model="::dane.zm2"></my-dir>
    <my-dir ng-model="::dane.zm3"></my-dir>
    <my-dir ng-model="::dane.zm4"></my-dir>
</div>
  </body>
</html>

我想通了。 使用 ng-model 指令(作为属性(会增加额外的观察程序。

结论:如果您不需要双向绑定或需要真正的一次性绑定,请不要使用 ng-model 作为属性。

angular.module("myApp", [])
            .controller("initCtrl", function ($scope, $interval) {
                $scope.dane = {
                    zm1: 'Directive 1 with onetime binding',
                    zm2: 'Directive 2 with onetime binding',
                    zm3: 'Directive 3 with onetime binding',
                    zm4: 'Directive 4 with onetime binding'
                };
                $scope.change = function () {
                    $scope.dane.zm1 = "Changed";
                };
                $interval(function () {
                    $scope.watchers = countWatchers();
                }, 1000);
            })
            .directive("myDir", function () {
                return {
                    scope: {
                        ngModel: "="
                    },
                    require: "ngModel",
                    link: function (scope, element, attrs, ctrl) {
                    },
                    template: "<div>{{::ngModel}} - extra watcher due to ngModel</div>"
                }
            })
            .directive("myDirNgModel", function () {
                return {
                    scope: {
                        ngModel: "="
                    },
                    require: "ngModel",
                    link: function (scope, element, attrs, ctrl) {
                    },
                    template: "<div>{{ngModel}} - three extra watcher - ngModel, declaration, directive</div>"
                }
            })
            .directive("ngBindOneWay", function () {
                return {
                    scope: {
                        var: "@"
                    },
                    link: function (scope, element, attrs, ctrl) {
                    },
                    template: "<div>{{::var}} - no extra watchers</div>"
                }
            })
            .directive("ngBindTwoWayOneTime", function () {
                return {
                    scope: {
                        var: "="
                    },
                    link: function (scope, element, attrs, ctrl) {
                    },
                    template: "<div>{{::var}} - no extra watchers</div>"
                }
            })
            .directive("ngBindTwoWay", function () {
                return {
                    scope: {
                        var: "="
                    },
                    link: function (scope, element, attrs, ctrl) {
                    },
                    template: "<div>{{var}} - two extra watchers - declaration and directive</div>"
                }
            })
            .directive("myDirNoBind", function () {
                return {
                    scope: {},
                    link: function (scope, element, attrs) {
                    },
                    template: "<div>No bindings - no extra watchers</div>"
                }
            })
    ;
    /**
     * Funkcja do zliczania watchers - max 2000
     */
    (function () {
        window.countWatchers = function () {
            var root = angular.element(document.getElementsByTagName('body'));
            var watchers = [];
            var f = function (element) {
                angular.forEach(['$scope', '$isolateScope'], function (scopeProperty) {
                    if (element.data() && element.data().hasOwnProperty(scopeProperty)) {
                        angular.forEach(element.data()[scopeProperty].$$watchers, function (watcher) {
                            watchers.push(watcher);
                        });
                    }
                });
                angular.forEach(element.children(), function (childElement) {
                    f(angular.element(childElement));
                });
            };
            f(root);
            // Remove duplicate watchers
            var watchersWithoutDuplicates = [];
            angular.forEach(watchers, function (item) {
                if (watchersWithoutDuplicates.indexOf(item) < 0) {
                    watchersWithoutDuplicates.push(item);
                }
            });
            return watchersWithoutDuplicates.length;
        };
    })();
<!DOCTYPE html>
<html>
  <head>
    <script data-require="angular.js@1.3.6" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body data-ng-app="myApp">
<div ng-controller="initCtrl" class="container">
    <div class="well">Watchers: {{watchers}} - first watcher</div>
    <my-dir ng-model="::dane.zm1"></my-dir>
    <my-dir-ng-model ng-model="dane.zm1"></my-dir-ng-model>
    <my-dir-no-bind></my-dir-no-bind>
    <ng-bind-one-way var="{{::dane.zm1}}"></ng-bind-one-way>
    <ng-bind-two-way var="dane.zm1"></ng-bind-two-way>
    <ng-bind-two-way-one-time var="::dane.zm1"></ng-bind-two-way-one-time>
    <div><a ng-click="change()" href="javascript:void(null)">Change zm1</a></div>
</div>
  </body>
</html>

相关内容

最新更新