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

Commit 092ef36

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 092ef36

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

src/ng/directive/input.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,11 @@ 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
1705+
* {@link input `input`}. so that when the expression change
1706+
* the element is set to the bound value.
1707+
*
1708+
*
17041709
* `ngValue` is useful when dynamically generating lists of radio buttons using
17051710
* {@link ngRepeat `ngRepeat`}, as shown below.
17061711
*
@@ -1711,7 +1716,7 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
17111716
*
17121717
* @element input
17131718
* @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute
1714-
* of the `input` element
1719+
* and `value` property of the element
17151720
*
17161721
* @example
17171722
<example name="ngValue-directive" module="valueExample">
@@ -1750,24 +1755,33 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
17501755
</example>
17511756
*/
17521757
var ngValueDirective = function() {
1758+
//helper function
1759+
var updateElementValue = function(element, attr, value) {
1760+
/**
1761+
* input use 'value attribute' as default value if 'value property has no value'
1762+
* but once set the 'value property' it will not read value from 'value attribute'
1763+
* so we set both the value attribute and property here to avoid this problem.
1764+
*/
1765+
attr.$set('value', value);
1766+
element.prop('value', value);
1767+
};
1768+
17531769
return {
17541770
restrict: 'A',
17551771
priority: 100,
17561772
compile: function(tpl, tplAttr) {
17571773
if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
17581774
return function ngValueConstantLink(scope, elm, attr) {
1759-
attr.$set('value', scope.$eval(attr.ngValue));
1775+
var value = scope.$eval(attr.ngValue);
1776+
updateElementValue(elm, attr, value);
17601777
};
17611778
} else {
17621779
return function ngValueLink(scope, elm, attr) {
17631780
scope.$watch(attr.ngValue, function valueWatchAction(value) {
1764-
attr.$set('value', value);
1781+
updateElementValue(elm, attr, value);
17651782
});
17661783
};
17671784
}
17681785
}
17691786
};
17701787
};
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)