问题
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