regularjs / regular

regularjs: a living template engine that helps us to create data-driven component.
http://regularjs.github.io/
MIT License
1.06k stars 149 forks source link

为什么明明没有values 但是第一个值为0? #159

Closed swit1983 closed 7 years ago

swit1983 commented 7 years ago

我是将regular ui 的 selectgroup 改为了 selectMultipleGroup。初始化的时候第一个select 会默认选中第一个不知为什么,不知道哪里赋的值,代码在下面可以直接跑

var template1 = '<select class="form-control {class}" r-model={value} readonly={readonly} \
    disabled={disabled} multiple="multiple"> \
    {#if placeholder}<option value="">{placeholder}</option>{/if} \
    {#list source as item} \
    <option value={item_index} disabled={item.disabled}>{item.name}</option> \
    {/list}\
</select>\
{#if buttons}\
    <div class="row">\
     {#list buttons as btn}\
     {/list}\
    </div>\
{/if}\
';

/**
 * @class Select1
 * @extend SourceComponent
 * @param {object}                  options.data                     =  绑定属性
 * @param {object[]=[]}             options.data.source             <=> 数据源
 * @param {string}                  options.data.source[].name       => 每项的内容
 * @param {boolean=false}           options.data.source[].disabled   => 禁用此项
 * @param {string|number}           options.data.value              <=> 当前选择值
 * @param {string='请选择'}         options.data.placeholder         => 默认项的文字,如果`placeholder`为空并且没有选择项时,将会自动选中第一项。
 * @param {boolean=false}           options.data.readonly            => 是否只读
 * @param {boolean=false}           options.data.disabled            => 是否禁用
 * @param {boolean=true}            options.data.visible             => 是否显示
 * @param {string=''}               options.data.class               => 补充class
 * @param {object}                  options.service                 @=> 数据服务
 */
window.MultipleSelect = Regular.extend({
    name: 'multipleSelect',
    template: template1,
    /**
     * @protected
     */
    config: function() {
        this.supr();

        this.$watch('selected', function(newValue, oldValue) {
            // this.data.value = newValue ? newValue[this.data.key] : newValue;

            /**
             * @event change 选择项改变时触发
             * @property {object} sender 事件发送对象
             * @property {object} selected 改变后的选择项
             * @property {string|number} value 改变后的选择值
             */
            this.$emit('change', {
                sender: this,
                selected: newValue,
                value: this.data.value
            });
        });

        this.$watch('value', function(newValue, oldValue) {
            if(newValue === '' || newValue === undefined)
                return this.data.selected = undefined;

            if(this.data.source)
                this.data.selected = this.data.source[newValue];
        });

        this.$watch('source', function(newValue, oldValue) {
            if(newValue === undefined)
                return this.data.value = '';

            if(!(newValue instanceof Array))
                throw new TypeError('`source` is not an Array!');

            if(newValue.length && (typeof newValue[0] === 'string' || typeof newValue[0] === 'number'))
                return this.data.source = newValue.map(function(name, index) {
                    return {id: index, name: name};
                });
        });
    }
});

var template = '<div class="col-md-12 {class}" r-hide={visible}>\
    {#list 0..(depth - 1) as i}\
    <div class="col-md-{12/depth-1}">\
    <multipleSelect source={sources[i]} value={values[i]} readonly={readonly} \
    disabled={disabled} placeholder={placeholders[i]} on-change={this._onChange($event, i)} />\
    </div>\
    {/list}\
</div>\
';
function _extend(o1, o2, override, hasOwnProperty) {
    for(var i in o2)
        if((!hasOwnProperty || o2.hasOwnProperty(i)) && (override || o1[i] === undefined))
            o1[i] = o2[i]
    return o1;
}
/**
 * @class SelectGroup
 * @extend Component
 * @param {object}                  options.data                     =  绑定属性
 * @param {object[]=[]}             options.data.source             <=> 数据源
 * @param {string}                  options.data.source[].name       => 每项的内容
 * @param {boolean=false}           options.data.source[].disabled   => 禁用此项
 * @param {number=1}                options.data.depth               => 层级数
 * @param {object}                  options.data.selected           <=  最后的选择项
 * @param {object[]=[]}             options.data.values    <=> 所有的选择项
 * @param {string[]=[]}             options.data.placeholders        => 默认项的文字
 * @param {boolean=false}           options.data.readonly            => 是否只读
 * @param {boolean=false}           options.data.disabled            => 是否禁用
 * @param {boolean=true}            options.data.visible             => 是否显示
 * @param {string=''}               options.data.class               => 补充class
 * @param {object}                  options.service                 @=> 数据服务
 */
var SelectMultipleGroup = Regular.extend({
    name: 'selectMultipleGroup',
    template: template,
    /**
     * @protected
     */
    config: function() {
        _extend(this.data, {
            // @inherited source: [],
            depth: 1,
            sources: [],
            selected: undefined,
            values: [],
            placeholders: []
        });
        this.supr();

        this.$watch('selected', function(newValue, oldValue) {
            /**
             * @event change 最后的选择项改变时触发
             * @property {object} sender 事件发送对象
             * @property {object} selected 最后的选择项
             * @property {object} values 所有的选择项
             */
            this.$emit('change', {
                sender: this,
                selected: newValue,
                values: this.data.values
            });
        });

        this.data.sources[0] = this.data.source;
    },
    /**
     * @private
     */
    _onChange: function($event, level) {
        var sources = this.data.sources;
        var item = sources[level] && sources[level][$event.value];

        // 由内部<select>控制
        // if(this.data.readonly || this.data.disabled || (item && (item.disabled || item.divider)))
        //     return;

        sources[level + 1] = item ? item.children : undefined;
        for(var i = level + 2; i < this.data.depth; i++)
            sources[i] = undefined;

        if(level === this.data.depth - 1)
            this.data.selected = item;

        /**
         * @event select 选择某一项时触发
         * @property {object} sender 事件发送对象
         * @property {object} selected 当前选择项
         * @property {object} level 当前选择的层级
         */
        this.$emit('select', {
            sender: this,
            selected: item,
            values: this.data.values,
            level: level
        });
    }
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app"></div>

<!-- 引入regular.js -->
<script src="regular.js"></script>
<script type="text/javascript" src="src/js/unit/selectMultiple.js"></script>
<script type="text/javascript" src="src/js/unit/selectMultipleGroup.js"></script>
<script>

// initialize component then $inject to #app's  bottom
var component = new SelectMultipleGroup({
  init:function(){
      this.$on("change",function(data){
          console.log(JSON.stringify(data.values));
      });
      this.$on("select",function(data){
          console.log(JSON.stringify(data.selected));
      });
  },
  data: {
    source: [
            {name: '北京', children: [
                {name: '北京', children: [
                    {name: '东城区'},
                    {name: '西城区'},
                    {name: '海淀区'},
                    {name: '朝阳区'},
                    {name: '丰台区'}
                ]}
            ]},
            {name: '上海', children: [
                {name: '上海', children: [
                    {name: '黄浦区'},
                    {name: '浦东新区'},
                    {name: '徐汇区'},
                    {name: '长宁区'}
                ]}
            ]},
            {name: '浙江', children: [
                {name: '杭州', children: [
                    {name: '上城区'},
                    {name: '下城区'},
                    {name: '江干区'},
                    {name: '西湖区'},
                    {name: '滨江区'}
                ]},
                {name: '宁波', children: [
                    {name: '海曙区'},
                    {name: '江东区'},
                    {name: '江北区'},
                    {name: '北仑区'},
                    {name: '镇海区'},
                    {name: '鄞州区'}
                ]},
                {name: '绍兴', children: [
                    {name: '越城区'},
                    {name: '柯桥区'},
                    {name: '上虞区'}
                ]}
            ]},
            {name: '江苏', children: [
                {name: '南京'},
                {name: '苏州'}
            ]}
        ],
        depth:3
  }
});
component.$inject('#app');

</script>   
</body>
</html>
z-ZYS-s commented 7 years ago

这个是Regular UI的Select2里面的特性,默认选中第一个。

swit1983 commented 7 years ago

我用的select1 只有第一个select会选中 但是第二个不会啊。没看出来啥区别 我把

// 当placeholder为空时,自动选择第一项
            if(!this.data.placeholder) {
                this.data.value = 0;
                this.data.selected = this.data.source[0];    // 手动更新
            } else
                this.data.value = '';

这段给去了,有这段会有问题。只会默认选中第一个select的第一项,后面2个select 会出现诡异问题

leeluolee commented 7 years ago

forward https://github.com/regularjs/regular-ui