@@ -11,65 +11,78 @@ ko.bindingHandlers['checked'] = {
11
11
return ko . utils . unwrapObservable ( allBindings . get ( 'value' ) ) ;
12
12
}
13
13
14
- return element . value ;
14
+ return useElementValue ? element . value : undefined ;
15
15
} ) ;
16
16
17
17
function updateModel ( ) {
18
18
// This updates the model value from the view value.
19
19
// It runs in response to DOM events (click) and changes in checkedValue.
20
20
var isChecked = element . checked ,
21
- elemValue = useCheckedValue ? checkedValue ( ) : isChecked ;
21
+ elemValue = checkedValue ( ) ;
22
22
23
23
// When we're first setting up this computed, don't change any model state.
24
24
if ( ko . computedContext . isInitial ( ) ) {
25
25
return ;
26
26
}
27
27
28
28
// We can ignore unchecked radio buttons, because some other radio
29
- // button will be getting checked, and that one can take care of updating state.
30
- if ( isRadio && ! isChecked ) {
29
+ // button will be checked, and that one can take care of updating state.
30
+ // Also ignore value changes to an already unchecked checkbox.
31
+ if ( ! isChecked && ( isRadio || ko . computedContext . getDependenciesCount ( ) ) ) {
31
32
return ;
32
33
}
33
34
34
35
var modelValue = ko . dependencyDetection . ignore ( valueAccessor ) ;
35
36
if ( valueIsArray ) {
36
- var writableValue = rawValueIsNonArrayObservable ? modelValue . peek ( ) : modelValue ;
37
- if ( oldElemValue !== elemValue ) {
37
+ var writableValue = rawValueIsNonArrayObservable ? modelValue . peek ( ) : modelValue ,
38
+ saveOldValue = oldElemValue ;
39
+ oldElemValue = elemValue ;
40
+
41
+ if ( saveOldValue !== elemValue ) {
38
42
// When we're responding to the checkedValue changing, and the element is
39
43
// currently checked, replace the old elem value with the new elem value
40
44
// in the model array.
41
45
if ( isChecked ) {
42
46
ko . utils . addOrRemoveItem ( writableValue , elemValue , true ) ;
43
- ko . utils . addOrRemoveItem ( writableValue , oldElemValue , false ) ;
47
+ ko . utils . addOrRemoveItem ( writableValue , saveOldValue , false ) ;
44
48
}
45
-
46
- oldElemValue = elemValue ;
47
49
} else {
48
50
// When we're responding to the user having checked/unchecked a checkbox,
49
51
// add/remove the element value to the model array.
50
52
ko . utils . addOrRemoveItem ( writableValue , elemValue , isChecked ) ;
51
53
}
54
+
52
55
if ( rawValueIsNonArrayObservable && ko . isWriteableObservable ( modelValue ) ) {
53
56
modelValue ( writableValue ) ;
54
57
}
55
58
} else {
59
+ if ( isCheckbox ) {
60
+ if ( elemValue === undefined ) {
61
+ elemValue = isChecked ;
62
+ } else if ( ! isChecked ) {
63
+ elemValue = undefined ;
64
+ }
65
+ }
56
66
ko . expressionRewriting . writeValueToProperty ( modelValue , allBindings , 'checked' , elemValue , true ) ;
57
67
}
58
68
} ;
59
69
60
70
function updateView ( ) {
61
71
// This updates the view value from the model value.
62
72
// It runs in response to changes in the bound (checked) value.
63
- var modelValue = ko . utils . unwrapObservable ( valueAccessor ( ) ) ;
73
+ var modelValue = ko . utils . unwrapObservable ( valueAccessor ( ) ) ,
74
+ elemValue = checkedValue ( ) ;
64
75
65
76
if ( valueIsArray ) {
66
77
// When a checkbox is bound to an array, being checked represents its value being present in that array
67
- element . checked = ko . utils . arrayIndexOf ( modelValue , checkedValue ( ) ) >= 0 ;
68
- } else if ( isCheckbox ) {
69
- // When a checkbox is bound to any other value (not an array), being checked represents the value being trueish
70
- element . checked = modelValue ;
78
+ element . checked = ko . utils . arrayIndexOf ( modelValue , elemValue ) >= 0 ;
79
+ oldElemValue = elemValue ;
80
+ } else if ( isCheckbox && elemValue === undefined ) {
81
+ // When a checkbox is bound to any other value (not an array) and "checkedValue" is not defined,
82
+ // being checked represents the value being trueish
83
+ element . checked = ! ! modelValue ;
71
84
} else {
72
- // For radio buttons , being checked means that the radio button's value corresponds to the model value
85
+ // Otherwise , being checked means that the checkbox or radio button's value corresponds to the model value
73
86
element . checked = ( checkedValue ( ) === modelValue ) ;
74
87
}
75
88
} ;
@@ -85,8 +98,8 @@ ko.bindingHandlers['checked'] = {
85
98
var rawValue = valueAccessor ( ) ,
86
99
valueIsArray = isCheckbox && ( ko . utils . unwrapObservable ( rawValue ) instanceof Array ) ,
87
100
rawValueIsNonArrayObservable = ! ( valueIsArray && rawValue . push && rawValue . splice ) ,
88
- oldElemValue = valueIsArray ? checkedValue ( ) : undefined ,
89
- useCheckedValue = isRadio || valueIsArray ;
101
+ useElementValue = isRadio || valueIsArray ,
102
+ oldElemValue = valueIsArray ? checkedValue ( ) : undefined ;
90
103
91
104
// IE 6 won't allow radio buttons to be selected unless they have a name
92
105
if ( isRadio && ! element . name )
0 commit comments