Radio/Checkbox: fix radio-radiogroup checkbox-checkboxgroup nested bug fixed #1152

pull/1333/head
qingwei.li 2016-11-25 13:13:41 +08:00
parent 6cd01c2647
commit 96f71eda55
7 changed files with 125 additions and 75 deletions

View File

@ -16,7 +16,12 @@
value(value) {
this.$emit('change', value);
this.dispatch('form-item', 'el.form.change', [value]);
this.broadcast('ElCheckbox', 'initData', [value]);
}
},
mounted() {
this.broadcast('ElCheckbox', 'initData', [this.value]);
}
};
</script>

View File

@ -17,11 +17,9 @@
:disabled="disabled"
:true-value="trueLabel"
:false-value="falseLabel"
v-model="_value"
v-model="model"
@focus="focus = true"
@blur="focus = false"
@change="handleChange"
ref="checkbox">
@blur="focus = false">
<input
v-else
class="el-checkbox__original"
@ -29,10 +27,9 @@
:disabled="disabled"
:value="label"
:name="name"
v-model="_value"
v-model="model"
@focus="focus = true"
@blur="focus = false"
@change="handleChange">
@blur="focus = false">
</span>
<span class="el-checkbox__label" v-if="$slots.default || label">
<slot></slot>
@ -48,6 +45,34 @@
mixins: [Emitter],
componentName: 'ElCheckbox',
computed: {
model: {
get() {
return this.isGroup ? this.store : this.value;
},
set(val) {
if (this.isGroup) {
this.dispatch('ElCheckboxGroup', 'input', [val]);
} else {
this.$emit('input', val);
}
}
},
isChecked() {
if ({}.toString.call(this.model) === '[object Boolean]') {
return this.model;
} else if (Array.isArray(this.model)) {
return this.model.indexOf(this.label) > -1;
} else if (this.model !== null && this.model !== undefined) {
return this.model === this.trueLabel;
}
}
},
props: {
value: {},
label: String,
@ -59,59 +84,30 @@
falseLabel: [String, Number]
},
computed: {
_value: {
get() {
return !this.wrapInGroup ? this.value : this.$parent.value;
},
set(newValue) {
if (!this.wrapInGroup) {
this.$emit('input', newValue);
} else {
this.$parent.$emit('input', newValue);
}
}
},
isChecked() {
var type = Object.prototype.toString.call(this._value);
if (type === '[object Boolean]') {
return this._value;
} else if (type === '[object Array]') {
return this._value.indexOf(this.label) > -1;
} else if (type === '[object String]' || type === '[object Number]') {
return this._value === this.trueLabel;
}
}
},
data() {
return {
focus: false,
wrapInGroup: this.$parent.$options.componentName === 'ElCheckboxGroup'
store: [],
isGroup: false
};
},
watch: {
checked: {
immediate: true,
handler(value) {
if (value) {
let type = Object.prototype.toString.call(this._value);
if (type !== '[object Array]') {
this._value = this.trueLabel || true;
} else {
this._value.push(this.label);
}
}
methods: {
addToStore() {
if (Array.isArray(this.model)) {
this.model.indexOf(this.label) === -1 && this.model.push(this.label);
} else {
this.model = this.trueLabel || true;
}
}
},
methods: {
handleChange(ev) {
this.$emit('change', ev);
}
created() {
this.checked && this.addToStore();
this.$on('initData', data => {
this.store = data;
this.isGroup = true;
this.checked && this.addToStore();
});
}
};
</script>

View File

@ -4,7 +4,7 @@
export default {
name: 'ElRadioGroup',
componentName: 'radio-group',
componentName: 'ElRadioGroup',
mixins: [Emitter],
@ -15,8 +15,12 @@
watch: {
value(value) {
this.$emit('change', value);
this.broadcast('ElRadio', 'initData', value);
this.dispatch('form-item', 'el.form.change', [this.value]);
}
},
mounted() {
this.broadcast('ElRadio', 'initData', this.value);
}
};
</script>

View File

@ -4,14 +4,14 @@
<span class="el-radio__inner"
:class="{
'is-disabled': disabled,
'is-checked': _value === label,
'is-checked': store === label,
'is-focus': focus
}"></span>
<input
class="el-radio__original"
:value="label"
type="radio"
v-model="_value"
v-model="store"
@focus="focus = true"
@blur="focus = false"
:name="name"
@ -24,9 +24,15 @@
</label>
</template>
<script>
import Emitter from 'element-ui/src/mixins/emitter';
export default {
name: 'ElRadio',
mixins: [Emitter],
componentName: 'ElRadio',
props: {
value: [String, Number],
label: {
@ -36,24 +42,34 @@
disabled: Boolean,
name: String
},
data() {
return {
focus: false
focus: false,
isGroup: false,
store: this.value
};
},
computed: {
_value: {
get() {
return this.value !== undefined ? this.value : this.$parent.value;
},
set(newValue) {
if (this.value !== undefined) {
this.$emit('input', newValue);
} else {
this.$parent.$emit('input', newValue);
}
watch: {
store(store) {
if (this.isGroup) {
this.dispatch('ElRadioGroup', 'input', store);
} else {
this.$emit('input', store);
}
},
value(val) {
this.store = val;
}
},
created() {
this.$on('initData', data => {
this.store = data;
this.isGroup = true;
});
}
};
</script>

View File

@ -5,7 +5,7 @@ function broadcast(componentName, eventName, params) {
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params));
} else {
broadcast.apply(child, [componentName, eventName].concat(params));
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}

View File

@ -67,6 +67,33 @@ describe('Checkbox', () => {
done();
});
});
it('nested group', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList">
<el-row>
<el-checkbox label="a" ref="a"></el-checkbox>
<el-checkbox label="b" ref="b"></el-checkbox>
<el-checkbox label="c" ref="c"></el-checkbox>
<el-checkbox label="d" ref="d"></el-checkbox>
</el-row>
</el-checkbox-group>
`,
data() {
return {
checkList: []
};
}
}, true);
expect(vm.checkList.length === 0).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
done();
});
});
it('true false label', done => {
vm = createVue({
template: `

View File

@ -65,14 +65,16 @@ describe('Radio', () => {
};
}
}, true);
expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok;
let radioElm = vm.$refs.radio2.$el;
radioElm.click();
vm.$nextTick(_ => {
expect(radioElm.querySelector('.is-checked')).to.be.ok;
expect(vm.radio === 6).to.be.true;
done();
});
setTimeout(_ => {
expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok;
let radioElm = vm.$refs.radio2.$el;
radioElm.click();
vm.$nextTick(_ => {
expect(radioElm.querySelector('.is-checked')).to.be.ok;
expect(vm.radio === 6).to.be.true;
done();
});
}, 50);
});
it('radio button', done => {
vm = createVue({