From 26207db6fd22aaeaf184fbc8b6607d7090a8b85d Mon Sep 17 00:00:00 2001 From: Gonzalo Ruiz de Villa Date: Wed, 1 May 2013 00:19:14 +0200 Subject: [PATCH] fix(input): detect changes in array when its values are changed 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 #1751 --- src/ng/directive/input.js | 32 +++++++++++++++++++++++++++----- test/ng/directive/inputSpec.js | 14 ++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 8ab6f696ca81..60f52d07e37f 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -1006,6 +1006,29 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ $element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS); }; + var ctrl = this; + + function outOfSyncWithModel(value) { + if (ctrl.$modelValue !== value) { + return true; + } + if (isArray(value)) { + return !equals(ctrl.$modelArrayValues, value); + } + return false; + } + + function storeArrayValues(value) { + ctrl.$modelArrayValues = [].concat(value); + } + + function storeValue(value) { + ctrl.$modelValue = value; + if (isArray(value)) { + storeArrayValues(value); + } + } + /** * @ngdoc function * @name ng.directive:ngModel.NgModelController#$setViewValue @@ -1039,7 +1062,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ }); if (this.$modelValue !== value) { - this.$modelValue = value; + storeValue(value); ngModelSet($scope, value); forEach(this.$viewChangeListeners, function(listener) { try { @@ -1052,18 +1075,17 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ }; // model -> value - var ctrl = this; $scope.$watch(function ngModelWatch() { var value = ngModelGet($scope); - // if scope model value and ngModel value are out of sync - if (ctrl.$modelValue !== value) { + if (outOfSyncWithModel(value)) { var formatters = ctrl.$formatters, idx = formatters.length; - ctrl.$modelValue = value; + storeValue(value); + while(idx--) { value = formatters[idx](value); } diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index f8898074f13e..4a89dd7292d4 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -990,6 +990,20 @@ describe('input', function() { }); + it("should detect changes in the values of an array", function () { + var list = ['x', 'y', 'z']; + compileInput(''); + scope.$apply(function() { + scope.list = list; + }); + expect(inputElm.val()).toBe('x, y, z'); + scope.$apply(function() { + list.unshift('w'); + }); + expect(inputElm.val()).toBe('w, x, y, z'); + }); + + xit('should require at least one item', function() { compileInput('');