简体   繁体   English

如何从指令监听textarea的变化?

[英]How to listen for changes in textarea from directive?

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. 指令autoexpand会根据您写入的行数将行添加到textarea中。 (it has nowrap set in css) (它的nowrap设置在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 在那种情况下,我也该如何运行expand() (我尝试了element.on('change'...element.change(element.bind('change'但似乎完全没有触发

You should be listening for change on ngModel this way: 您应该这样监听ngModel更改:

// 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. 尽管您当然可以观看'tasks.tasks' ,但这将把指令的用处仅限于一个用例。

you can listen in on ngModel changes by doing somethign like this: 您可以通过执行以下操作来监听ngModel的变化:

scope.$on("ngModel", function(){
    //this will fire when ng model changes
}, true);

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): 您可以在指令中有一个$watch ,它会在模型​​更改时触发(无论它如何更改):

scope.$watch(attrs.ngModel, function(){
    expand(element);
});

You don't even need the keydown event handler anymore. 您甚至不再需要keydown事件处理程序。 The only other thing you need to do is add ng-trim="false" to the text area. 您需要做的唯一另一件事是将ng-trim="false"到文本区域。 Otherwise, the model will ignore whitespace (including any new lines that you type). 否则,模型将忽略空格(包括您键入的任何新行)。

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM