-
Notifications
You must be signed in to change notification settings - Fork 27.5k
ngModel + ngList binding to array does not update view when model changes #1751
Comments
When model value is an array, its values must be stored in a new array to allow a comparison between old and new values when checking if a value is out of sync with the model. Closes angular#1751
When model changes are detected, a equality comparison with a local copy of the value ($modelValue). ngModelController provides the method $setCompareByEquality to change between equality and reference comparisons. Closes angular#1751
As part of our effort to clean out old issues, this issue is being automatically closed since it has been inactivite for over two months. Please try the newest versions of Angular ( Thanks! |
The issue hasn't been fixed in either version. |
…he former array data related to angular#1751 When watching arrays, $watchCollection returned the new data both in the newCollection and the oldCollection arguments of the listener
fixes angular#1751 When the model referenced the same same array and the array values where changed, the list wasn't updated. Now watchCollection is used to detect changes in NgModelController. isEmpty now detects empty arrays BEHAVIOUR CHANGE There is a change in the behaviour of ngList when typing a list. When “a , b” is typed is automatically changed to “a, b”.
…he former array data related to angular#1751 When watching arrays, $watchCollection returned the new data both in the newCollection and the oldCollection arguments of the listener
fixes angular#1751 When the model referenced the same same array and the array values where changed, the list wasn't updated. Now watchCollection is used to detect changes in NgModelController. Changes in input.js breaked tests: — select select-multiple should require — select ngOptions ngRequired should treat an empty array as invalid when `multiple` attribute used Changes in select.js fixed them again: changes in the collections should trigger the formatters and render again. BEHAVIOUR CHANGE There is a change in the behaviour of ngList when typing a list. When “a , b” is typed is automatically changed to “a, b”.
I also encounter this issue when using ng-model in my custom directive. It seems ngModelController using reference comparison leads the $render callback never being called when array is just an old reference but its content changes. angular v1.2.23 |
Workaround: make a new directive, something like:
(untested, may need tweaking) |
👍 Just formatting Jamie's workaround function ngeModelCollection() {
return {
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
$scope.$watchCollection(attr.ngModel, function ngModelWatch(value, old) {
if (!Array.isArray(value) || old === value) {
return;
}
///copypasta from ngModelWatch()
var formatters = ctrl.$formatters,
idx = formatters.length;
ctrl.$modelValue = value;
while (idx--) {
value = formatters[idx](value);
}
if (ctrl.$viewValue !== value) {
ctrl.$viewValue = value;
ctrl.$render();
}
});
////endcopypasta
}//end link function
};
} |
I've created this workaround via new directive. angular.module('myApp')
.directive('emNgList', emNgList)
;
function emNgList(){
return {
restrict: 'A',
require: 'ngModel',
priority: 100, // this has to be eq or gt as ngList.priority to get ngList $formatter
link: postLink
};
function postLink(scope, elem, attrs, ctrl){
var ngListFormatter = getNgListFormatter(ctrl);
var killMe = scope.$watchCollection(attrs.ngModel, function(modelValue){
var newViewValue = ngListFormatter(modelValue);
if(newViewValue !== ctrl.$viewValue){
ctrl.$viewValue = newViewValue;
ctrl.$render();
}
});
scope.$on('$destroy',function(){ killMe(); });
}
function getNgListFormatter(ngModelCtrl){
var formatters = ngModelCtrl.$formatters;
var lastIdx = formatters.length - 1;
return formatters[lastIdx];
}
} showcase: |
See: http://jsfiddle.net/fjQcu/4/
The reason for that is object reference comparison at input.js:1050
The text was updated successfully, but these errors were encountered: