我写了一条指令,该指令可以自动扩展返回键上的文本区域。但是,当我预填充textarea时,我希望它增长到内容的大小。
当数据需要一点加载时,我的观察者会入睡。我必须单击文本区域以与其进行交互,以使其最初自动展开。
理想情况下,在初始自动扩展完成后,我想停止监视程序,但不停止输入侦听器。
这是我的代码
angular.module('app',[])
.controller('mainCtrl', function($timeout) {
var vm = this;
vm.tab = 1;
//fake async call
$timeout(function() {
vm.text = 'fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r ';
}, 1500);
})
.directive('autoResize', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function autoResizeLink(scope, element, attrs, ngModel) {
scope.$watch(function() {
console.log('listen');
if((ngModel.$viewValue || ngModel.$modelValue) && element[0].scrollHeight > 0) {
console.log('view value appeared', ngModel.$viewValue);
console.log('element[0].scrollHeight',element[0].scrollHeight);
element.css({ 'height': 'auto', 'overflow-y': 'hidden' });
element.css('height', element[0].scrollHeight + 'px');
console.log('stop listening here');
}
});
element.on('input', function () {
element.css({ 'height': 'auto', 'overflow-y': 'hidden' });
element.css('height', element[0].scrollHeight + 'px');
});
}
}
});
a {
text-decoration: underline;
color: blue;
cursor: pointer;
}
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
</head>
<body>
<div ng-controller="mainCtrl as vm">
<a ng-click="vm.tab = 1">Tab 1</a>
<a ng-click="vm.tab = 2">Tab 2</a>
<div ng-show="vm.tab === 2">
<textarea auto-resize ng-model="vm.text"></textarea>
</div>
</div>
</body>
</html>
代替使用监视程序,而使用$formatters和$viewChangeListeners管道:
app.directive('autoResize', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function autoResizeLink(scope, element, attrs, ngModel) {
ngModel.$formatters.push(function(data) {
$timeout(resize);
return data;
});
ngModel.$viewChangeListeners.push(function() {
$timeout(resize);
});
function resize() {
console.log("resize");
element.css({ 'height': 'auto', 'overflow-y': 'hidden' });
element.css('height', element[0].scrollHeight + 'px');
}
}
}
});
ngModelController从框架获取新模型值时会调用$formatters函数。当它从用户那里获取新值时,它将调用$viewChangeListeners。
angular.module('app',[])
.controller('mainCtrl', function($timeout) {
var vm = this;
vm.tab = 1;
//fake async call
$timeout(function() {
console.log("data");
vm.text = 'fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r fsafsafsafasfsa \r ';
}, 1500);
})
.directive('autoResize', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function autoResizeLink(scope, element, attrs, ngModel) {
ngModel.$formatters.push(function(data) {
$timeout(resize);
return data;
});
ngModel.$viewChangeListeners.push(function() {
$timeout(resize);
});
function resize() {
console.log("resize");
element.css({ 'height': 'auto', 'overflow-y': 'hidden' });
element.css('height', element[0].scrollHeight + 'px');
}
}
}
});
a {
text-decoration: underline;
color: blue;
cursor: pointer;
}
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
</head>
<body>
<div ng-controller="mainCtrl as vm">
<a ng-click="vm.tab = 1">Tab 1</a>
<a ng-click="vm.tab = 2">Tab 2</a>
<div ng-if="vm.tab === 2">
<textarea auto-resize ng-model="vm.text"></textarea>
</div>
</div>
</body>
</html>