8000 v-model: checkbox support array model + use afterBind for initializin… · bencode/vue@22c8a49 · GitHub
[go: up one dir, main page]

Skip to content

Commit 22c8a49

Browse files
committed
v-model: checkbox support array model + use afterBind for initializing inline value
1 parent c427029 commit 22c8a49

File tree

5 files changed

+62
-55
lines changed

5 files changed

+62
-55
lines changed

src/directive.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,11 @@ Directive.prototype._bind = function () {
116116
scope: this._scope
117117
}
118118
)
119-
if (this._initValue != null) {
120-
watcher.set(this._initValue)
119+
// v-model with inital inline value need to sync back to
120+
// model instead of update to DOM on init. They would
121+
// set the afterBind hook to indicate that.
122+
if (this.afterBind) {
123+
this.afterBind()
121124
} else if (this.update) {
122125
this.update(watcher.value)
123126
}

src/directives/public/model/checkbox.js

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,7 @@ module.exports = {
66
var self = this
77
var el = this.el
88

9-
this._matchValue = function (value) {
10-
if (el.hasOwnProperty('_trueValue')) {
11-
return _.looseEqual(value, el._trueValue)
12-
} else {
13-
return !!value
14-
}
15-
}
16-
17-
function getValue () {
9+
function getBooleanValue () {
1810
var val = el.checked
1911
if (val && el.hasOwnProperty('_trueValue')) {
2012
return el._trueValue
@@ -25,16 +17,44 @@ module.exports = {
2517
return val
2618
}
2719

28-
this.on('change', function () {
29-
self.set(getValue())
30-
})
20+
this.listener = function () {
21+
var model = self._watcher.value
22+
if (_.isArray(model)) {
23+
var val = getValue(el)
24+
if (el.checked) {
25+
if (_.indexOf(model, val) < 0) {
26+
model.push(val)
27+
}
28+
} else {
29+
model.$remove(val)
30+
}
31+
} else {
32+
self.set(getBooleanValue())
33+
}
34+
}
3135

36+
this.on('change', this.listener)
3237
if (el.checked) {
33-
this._initValue = getValue()
38+
this.afterBind = this.listener
3439
}
3540
},
3641

3742
update: function (value) {
38-
this.el.checked = this._matchValue(value)
43+
var el = this.el
44+
if (_.isArray(value)) {
45+
el.checked = _.indexOf(value, getValue(el)) > -1
46+
} else {
47+
if (el.hasOwnProperty('_trueValue')) {
48+
el.checked = _.looseEqual(value, el._trueValue)
49+
} else {
50+
el.checked = !!value
51+
}
52+
}
3953
}
4054
}
55+
56+
function getValue (el) {
57+
return el.hasOwnProperty('_value')
58+
? el._value
59+
: el.value
60+
}

src/directives/public/model/radio.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ module.exports = {
1919
return val
2020
}
2121

22-
this.on('change', function () {
22+
this.listener = function () {
2323
self.set(self.getValue())
24-
})
24+
}
25+
this.on('change', this.listener)
2526

2627
if (el.checked) {
27-
this._initValue = this.getValue()
28+
this.afterBind = this.listener
2829
}
2930
},
3031

src/directives/public/model/select.js

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,26 @@ module.exports = {
1414
}
1515

1616
this.number = this.param('number') != null
17-
this.multiple = el.hasAttribute('multiple')
17+
var multiple = this.multiple = el.hasAttribute('multiple')
1818

1919
// attach listener
20-
this.on('change', function () {
21-
var value = getValue(el, self.multiple)
20+
this.listener = function () {
21+
var value = getValue(el, multiple)
2222
value = self.number
2323
? _.isArray(value)
2424
? value.map(_.toNumber)
2525
: _.toNumber(value)
2626
: value
2727
self.set(value)
28-
})
28+
}
29+
this.on('change', this.listener)
2930

30-
// check initial value (inline selected attribute)
31-
checkInitialValue.call(this)
31+
// if has initial value, set afterBind
32+
var initValue = getValue(el, multiple, true)
33+
if ((multiple && initValue.length) ||
34+
(!multiple && initValue !== null)) {
35+
this.afterBind = this.listener
36+
}
3237

3338
// All major browsers except Firefox resets
3439
// selectedIndex with value -1 to 0 when the element
@@ -63,44 +68,24 @@ module.exports = {
6368
}
6469
}
6570

66-
/**
67-
* Check the initial value for selected options.
68-
*/
69-
70-
function checkInitialValue () {
71-
var initValue
72-
var options = this.el.options
73-
for (var i = 0, l = options.length; i < l; i++) {
74-
if (options[i].hasAttribute('selected')) {
75-
if (this.multiple) {
76-
(initValue || (initValue = []))
77-
.push(options[i].value)
78-
} else {
79-
initValue = options[i].value
80-
}
81-
}
82-
}
83-
if (typeof initValue !== 'undefined') {
84-
this._initValue = this.number
85-
? _.toNumber(initValue)
86-
: initValue
87-
}
88-
}
89-
9071
/**
9172
* Get select value
9273
*
9374
* @param {SelectElement} el
9475
* @param {Boolean} multi
76+
* @param {Boolean} init
9577
* @return {Array|*}
9678
*/
9779

98-
function getValue (el, multi) {
80+
function getValue (el, multi, init) {
9981
var res = multi ? [] : null
100-
var op, val
82+
var op, val, selected
10183
for (var i = 0, l = el.options.length; i < l; i++) {
10284
op = el.options[i]
103-
if (op.selected) {
85+
selected = init
86+
? op.hasAttribute('selected')
87+
: op.selected
88+
if (selected) {
10489
val = op.hasOwnProperty('_value')
10590
? op._value
10691
: op.value

src/directives/public/model/text.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,7 @@ module.exports = {
112112
el.hasAttribute('value') ||
113113
(el.tagName === 'TEXTAREA' && el.value.trim())
114114
) {
115-
this._initValue = number
116-
? _.toNumber(el.value)
117-
: el.value
115+
this.afterBind = this.listener
118116
}
119117
},
120118

0 commit comments

Comments
 (0)
0