对于没有任何 Promise 的指令,我们可以使用另一个指令 $compile 它的元素,然后在 $compile 的回调函数中调用 $timeout 而不进行脏检查(第三个参数 - 假):
app.directive('measure', function () {
return {
controller: function ($scope, $element, $compile, $timeout, $window) {
$window.start = new Date().getTime();
// make sure to compile only once
if (!$window.done) {
console.log('STARTING MEASUREMENT');
$window.done = true;
$compile($element)($scope, function(clonedElement, scope) {
var timer = $timeout(function () {
console.log('ENDING MEASUREMENT: ' + (new Date().getTime() - $window.start) + 'ms');
$timeout.cancel(timer);
}, 0, false);
});
}
}
};
})
对于带有 Promise 的指令,我们可以再次使用 $timeout 来测量它,而无需脏检查,而是在最后一个 Promise 的 then 块中调用:
app.directive('someOtherDir', function () {
return {
template: '<div ng-repeat="item in vm.data"><img ng-src="{{ item.thumbnailUrl }}" title="{{ item.title }}"></div>',
controller: function ($http, $timeout, $window) {
console.log('STARTING MEASUREMENT');
$window.start = new Date().getTime();
var vm = this;
$http.get('data.json').then(function (res) {
vm.data = res.data;
var timer = $timeout(function () {
console.log('ENDING MEASUREMENT: ' + (new Date().getTime() - $window.start) + 'ms');
$timeout.cancel(timer);
}, 0, false);
});
},
controllerAs: 'vm'
};
});
这是我的playground plunkerhttp://plnkr.co/edit/McWOeF7rZ7ZYKnDWafy6?p=preview,注释/取消注释2个指令,尝试在someDir指令中增加i:
for (var i = 0; i < 20; i++) {
vm.dates.push({
timestamp: i * 1000 * 60 * 60 * 24,
label: new Date(i * 1000 * 60 * 60 * 24).toString()
});
}
尝试 200、2000...