Directive doesn't fire after changing textarea model

£可爱£侵袭症+ 提交于 2019-12-23 17:43:54

问题


I have a text with newline separator and URLs:

first row\nFind me at http://www.example.com and also\n at http://stackoverflow.com.

I want to update ng-repeat values after pressing on copy button.

I have this HTML:

<div ng-controller="myCntrl">
    <textarea ng-model="copy_note_value"></textarea>

    <button data-ng-click="copy()">copy</button>

    <div>
        <p ng-repeat="row in note_value.split('\n') track by $index"
           wm-urlify="row"
           style="display: inline-block;"
            >
        </p>
    </div>
</div>

Controller:

app.controller('myCntrl', function ($scope) {

     $scope.note_value = "first row\nFind me at http://www.example.com and also\n at http://stackoverflow.com";

     $scope.copy_note_value = angular.copy($scope.note_value);

    $scope.copy = function(){
      $scope.note_value = angular.copy($scope.copy_note_value);   
    }

});

I have directive that should take text and return urlfied text:

app.directive('wmUrlify', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, element, attrs) {

            function urlify(text) {
                var urlRegex = /(https?:\/\/[^\s]+)/g;
                return text.replace(urlRegex, function (url) {
                    return '<a href="' + url + '" target="_blank">' + url + '</a>';
                })
            }

            var text = $parse(attrs.wmUrlify)(scope);
            var html = urlify(text);
            element[0].inneHtml(html)

        }
    };
}]);

Here is a flow: User changes text in textarea and presses on copy button. I expect to show the change in ng-repeat.

It works only if I add a new line and not line content.

What is wrong here? This is my Fiddle


回答1:


Just remove the track by $index from your ng-repeat. This is because you are telling Angular that the value of note_value.split('\n') will only be changed when there is a change in the $index i.e. size of the array after splitting by new line.

But the default implementation of track by is the identity of each item. So when you changed the default implementation to track it by the $index and when you are not not adding a new line instead just updating the content of any existing line, Angular is not able to detect that there is a change.

Update

Removing the track by $index function will throw an exception when there are same values after split. So you can use a simple function like: (define it in your controller)

$scope.indexFunction = function($index, val) {
    // Creating an unique identity based on the index and the value
    return $index + val;
};

And then use it in your ng-repeat like:

<p ng-repeat="row in note_value.split('\n') track by indexFunction($index, row)"></p>

https://docs.angularjs.org/api/ng/directive/ngRepeat



来源:https://stackoverflow.com/questions/34265554/directive-doesnt-fire-after-changing-textarea-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!