我正在编写一个简单的Angular指令,该指令用于在旁边显示行号textarea
。但是,由于某些原因,$ watch表达式不会触发更新。这是代码:
mod.directive('newTextArea', function() {
return {
restrict: 'E',
scope: {
query: '='
},
template:
'<div>' +
' <div ng-style="{height: height}" style="width: 20px; float: left; color: gray; font-family: Courier New; font-size: 14px; overflow: hidden; height: 85px; position: relative; top: 5px;">' +
' <div style="position: absolute">' +
' <span ng-repeat="line in lines">{{line}}<br></span>' +
' </div>' +
' </div>' +
' <textarea id="query-area" style="overflow-x: scroll; font-family: Courier New; font-size: 14px;">' +
' </textarea> {{ lines }}' +
'</div>',
controller: function($scope, $attrs, $element) {
var textarea = document.getElementById('query-area');
function updateLayout() {
var st = textarea.scrollTop;
var h = textarea.scrollHeight;
$scope.height = h;
console.log(st, h);
if (st !== undefined && h !== undefined) {
var start = Math.round(st / 14);
var stop = Math.round((st + h) / 14);
$scope.lines = _.range(start+1, stop+1);
}
}
$scope.$watch(
function() {
return [textarea.scrollHeight, textarea.scrollTop];
}, updateLayout, true
);
}
};
滚动文本区域或更改其大小后,行号应立即更新。知道为什么这行不通吗?
观察者在摘要循环中运行。在文本区域中写入不会导致摘要循环开始,因此将永远不会执行观察程序。
例如,如果您将其添加ng-model="something"
到textarea
元素,它将自此开始工作,然后Angular将绑定到一堆事件,并在事件触发时在内部触发摘要循环。
无需依赖其他事物来触发摘要循环,您可以将替换为$watch
以下内容:
var listener = function() {
$scope.$apply(updateLayout);
};
angular.element(textarea).on('keyup keydown keypress change', listener);
updateLayout();
$scope.$on('$destroy', function () {
angular.element(textarea).off('keyup keydown keypress change', listener);
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句