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

Commit ceb1471

Browse files
committed
fix(ngChecked): ensure that ngChecked doesn't interfere with ngModel
Fixes #10662
1 parent 6018f5d commit ceb1471

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

src/ng/directive/attrs.js

+20-7
Original file line numberDiff line numberDiff line change
@@ -341,22 +341,35 @@
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

350-
var normalized = directiveNormalize('ng-' + attrName);
349+
function defaultLinkFn(scope, element, attr) {
350+
scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
351+
attr.$set(attrName, !!value);
352+
});
353+
}
354+
355+
var normalized = directiveNormalize('ng-' + attrName),
356+
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+
// - https://github.com/angular/angular.js/issues/10662
362+
if (attr.ngModel !== attr[normalized]) {
363+
defaultLinkFn(scope, element, attr);
364+
}
365+
};
366+
}
367+
351368
ngAttributeAliasDirectives[normalized] = function() {
352369
return {
353370
restrict: 'A',
354371
priority: 100,
355-
link: function(scope, element, attr) {
356-
scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
357-
attr.$set(attrName, !!value);
358-
});
359-
}
372+
link: linkFn
360373
};
361374
};
362375
});

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)