Reputation: 15006
I have a textarea that looks like this:
<textarea ng-controller="text" autoexpand id="tasks" ng-focus="uncheckAll()" ng-change="processText()" ng-model="tasks.tasks"></textarea>
The directive autoexpand is adding rows to the textarea based on how many lines you write. (it has nowrap set in css)
//adding rows to the textarea based on the number of newlines.
directive('autoexpand', function($timeout){
function expand(element){
var count = element.val().split('\n').length+1;
element.attr('rows', count)
}
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element){
//onload
$timeout(function(){
expand(element);
});
element.on('keydown', function (){
console.log('change')
expand(element)
});
}
}
}).
This works when I update the textarea by writing to it, but sometimes, It's updated from the model. How can I run expand()
also in that case (I tried element.on('change'...
, element.change(
and element.bind('change'
but it doesn't seem to trigger at all
Upvotes: 0
Views: 2099
Reputation: 5290
You want to listen to and react to the model (instead of the element) whenever possible. You can have a $watch
in the directive that will fire whenever the model changes (regardless of how it changes):
scope.$watch(attrs.ngModel, function(){
expand(element);
});
You don't even need the keydown
event handler anymore. The only other thing you need to do is add ng-trim="false"
to the text area. Otherwise, the model will ignore whitespace (including any new lines that you type).
Upvotes: 0
Reputation: 1446
You should be listening for change on ngModel
this way:
// here "model" is linked to ng-model property
scope.$watch("model", function() {
console.log("Changed");
expand(element);
});
Though you can certainly watch 'tasks.tasks'
, it will be limiting the usefulness of your directive to just one use case.
Upvotes: 1
Reputation: 28750
you can listen in on ngModel changes by doing somethign like this:
scope.$on("ngModel", function(){
//this will fire when ng model changes
}, true);
Upvotes: 0