Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 6f8aa1d

Browse files
committed
fix(ngValue): set value property and attribute instead of setting attribute only
input element reads the value from value property and override the value attribute so we need to set both Closes #14031 Closes #13984 BREAKING CHANGE: NgValue is no longer updating the "value attribute" only when the model change, because input element reads the value from "value attribute" only in case of "value property" has no value but when "value property" changed the input element will stop reading the value from "value attribute" and read it form the "value property". so the input value in the gui will not equal the value of the model, becuase the model update the "value attribute" only. Now ngValue updates both of "value attribute" and "value property" when the model change This shouldn't affect any application becuase this is a bug and input value in the gui should be updated when the model change
1 parent b8b5b88 commit 6f8aa1d

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

src/ng/directive/input.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,10 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
17011701
* so that when the element is selected, the {@link ngModel `ngModel`} of that element is set to
17021702
* the bound value.
17031703
*
1704+
* It can be used to achieve one-way binding of a given expression to the value of `element`,
1705+
* so that when the expression change the element is set to the bound value.
1706+
*
1707+
*
17041708
* `ngValue` is useful when dynamically generating lists of radio buttons using
17051709
* {@link ngRepeat `ngRepeat`}, as shown below.
17061710
*
@@ -1711,7 +1715,7 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
17111715
*
17121716
* @element input
17131717
* @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute
1714-
* of the `input` element
1718+
* and `value` property of the element
17151719
*
17161720
* @example
17171721
<example name="ngValue-directive" module="valueExample">
@@ -1750,24 +1754,33 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
17501754
</example>
17511755
*/
17521756
var ngValueDirective = function() {
1757+
//helper function
1758+
var updateElementValue = function(element, attr, value) {
1759+
/**
1760+
* input use 'value attribute' as default value if 'value property has no value'
1761+
* but once set the 'value property' it will not read value from 'value attribute'
1762+
* so we set both the value attribute and property here to avoid this problem.
1763+
*/
1764+
attr.$set('value', value);
1765+
element.prop('value', value);
1766+
};
1767+
17531768
return {
17541769
restrict: 'A',
17551770
priority: 100,
17561771
compile: function(tpl, tplAttr) {
17571772
if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
17581773
return function ngValueConstantLink(scope, elm, attr) {
1759-
attr.$set('value', scope.$eval(attr.ngValue));
1774+
var value = scope.$eval(attr.ngValue);
1775+
updateElementValue(elm, attr, value);
17601776
};
17611777
} else {
17621778
return function ngValueLink(scope, elm, attr) {
17631779
scope.$watch(attr.ngValue, function valueWatchAction(value) {
1764-
attr.$set('value', value);
1780+
updateElementValue(elm, attr, value);
17651781
});
17661782
};
17671783
}
17681784
}
17691785
};
17701786
};
1771-
1772-
1773-

test/ng/directive/inputSpec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,6 +3046,22 @@ describe('input', function() {
30463046
expect(inputElm[0].getAttribute('value')).toBe('something');
30473047
});
30483048

3049+
they('should update the $prop "value" property and attribute after change the "value" property', {
3050+
input: '<input type="text" ng-value="value">',
3051+
textarea: '<textarea ng-value="value"></textarea>'
3052+
}, function(tmpl) {
3053+
var element = helper.compileInput(tmpl);
3054+
3055+
helper.changeInputValueTo('newValue');
3056+
expect(element[0].value).toBe('newValue');
3057+
expect(element[0].getAttribute('value')).toBeNull();
3058+
3059+
$rootScope.$apply(function() {
3060+
$rootScope.value = 'anotherValue';
3061+
});
3062+
expect(element[0].value).toBe('anotherValue');
3063+
expect(element[0].getAttribute('value')).toBe('anotherValue');
3064+
});
30493065

30503066
it('should evaluate and set constant expressions', function() {
30513067
var inputElm = helper.compileInput('<input type="radio" ng-model="selected" ng-value="true">' +

0 commit comments

Comments
 (0)