每个指令都有一个额外的观察者吗? 以下是示例代码 - 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;
};
})();
&#13;
<!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>
&#13;
答案 0 :(得分:2)
我明白了。使用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>