在AngularJS中,您可以使用$watch
监视模型更改。所以,如果我写这样的话:
$scope.$watch('model', function (newValue, oldValue) {
// React to the change...
});
...然后当模型
$scope.model
更改并执行某些操作时,我会收到通知。但是,如果
model
绑定到AngularJS视图(即model.name
绑定到HTML页面上的用户名),则在触发$watch
回调时,此更改将不会传播到DOM。我的问题是:AngularJS何时将模型更改传播到DOM,我如何侦听该事件?
编辑
用例是制作一个绝对定位的滚动器,该滚动器具有可变大小的固定标题和滚动内容(请参阅此Plunk以获取想法:http://plnkr.co/edit/LdYl7e7GYhdGiF3NQ0Bv)
指令现在看起来像这样:
.directive('psScroller', function ($timeout) {
return {
require: 'ngModel',
replace: true,
restrict: 'A',
transclude: true,
scope: {
'model': '=ngModel'
},
controller: function ($scope) {
var _this = this;
var _headerElement;
var _contentElement;
$scope.resize = function () {
if (!_headerElement || !_contentElement) return;
$timeout(function() {
_contentElement.css('top', _headerElement.height())
});
};
this.setHeaderElement = function (headerElement) {
_headerElement = headerElement;
_headerElement.on('keydown', $scope.resize);
};
this.setContentElement = function (contentElement) {
_contentElement = contentElement;
};
},
link: function (scope) {
scope.$watch('model', function () {
scope.resize();
}, true);
},
template: '<div ng-transclude></div>'
};
});
因此,我的想法是调整内容高度以匹配标题高度。
最佳答案
Angular指令负责反映DOM中的模型更改。他们在模型元素上注册监视程序,并在调用这些监视程序时更改DOM。因此,当您监视与指令相同的模型属性时,您的监视侦听器可能在由相应伪指令注册的监视侦听器之前被调用,因此DOM尚未更改。
您可以在监视侦听器中使用超时或$scope.$evalAsync()
来延迟代码的执行,并等待DOM更改。两种解决方案如何不同,例如在this answer中解释了一个相关问题。