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

Commit e079111

Browse files
LeonardoBragacaitp
authored andcommitted
fix(ngChecked): ensure that ngChecked doesn't interfere with ngModel
Corrects an issue which occurs when an element's ng-modeol and ng-checked attributes have the same value. Closes #10662 Closes #10664
1 parent e1132f5 commit e079111

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

src/ng/directive/attrs.js

+18-6
Original file line numberDiff line numberDiff line change
@@ -341,22 +341,34 @@
341341

342342
var ngAttributeAliasDirectives = {};
343343

344-
345344
// boolean attrs are evaluated
346345
forEach(BOOLEAN_ATTR, function(propName, attrName) {
347346
// binding to multiple is not supported
348347
if (propName == "multiple") return;
349348

349+
function defaultLinkFn(scope, element, attr) {
350+
scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
351+
attr.$set(attrName, !!value);
352+
});
353+
}
354+
350355
var normalized = directiveNormalize('ng-' + attrName);
356+
var linkFn = defaultLinkFn;
357+
358+
if (propName === 'checked') {
359+
linkFn = function(scope, element, attr) {
360+
// ensuring ngChecked doesn't interfere with ngModel when both are set on the same input
361+
if (attr.ngModel !== attr[normalized]) {
362+
defaultLinkFn(scope, element, attr);
363+
}
364+
};
365+
}
366+
351367
ngAttributeAliasDirectives[normalized] = function() {
352368
return {
353369
restrict: 'A',
354370
priority: 100,
355-
link: function(scope, element, attr) {
356-
scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
357-
attr.$set(attrName, !!value);
358-
});
359-
}
371+
link: linkFn
360372
};
361373
};
362374
});

test/ng/directive/booleanAttrsSpec.js

+16
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@ describe('boolean attr directives', function() {
4242
}));
4343

4444

45+
it('should not bind checked when ngModel is present', inject(function($rootScope, $compile) {
46+
// test for https://github.com/angular/angular.js/issues/10662
47+
element = $compile('<input type="checkbox" ng-model="value" ng-false-value="\'false\'" ' +
48+
'ng-true-value="\'true\'" ng-checked="value" />')($rootScope);
49+
$rootScope.value = 'true';
50+
$rootScope.$digest();
51+
expect(element[0].checked).toBe(true);
52+
browserTrigger(element, 'click');
53+
expect(element[0].checked).toBe(false);
54+
expect($rootScope.value).toBe('false');
55+
browserTrigger(element, 'click');
56+
expect(element[0].checked).toBe(true);
57+
expect($rootScope.value).toBe('true');
58+
}));
59+
60+
4561
it('should bind selected', inject(function($rootScope, $compile) {
4662
element = $compile('<select><option value=""></option><option ng-selected="isSelected">Greetings!</option></select>')($rootScope);
4763
jqLite(document.body).append(element);

0 commit comments

Comments
 (0)