webix的Form綁定支持數組Array

綁定的原理

form.setValues:把樹形對象,壓平展開成一維的。好比:web

var data = {
    id: 11,
    name: {
        first: 'alex',
        last: 'wu'
    }
};

var dataCollapsed = {
    id: 11,
    name.first: 'alex',
    name.last: 'wu'
};

壓平以後,再根據key去賦值。
同理,form.getValues:是逆過程,把一維的數組合成樹形結構。
核心代碼是webix.CodeParser.collapseNames/expandNames,一看就明白。壓平展開collapseNames是個很好的遞歸的例子;合成樹形expandNames則是雙層循環。數組

支持數組Array綁定

但webix的實現裏不支持數組,WPF是支持的、Vue.js也支持。並且實際的場景裏,有時確實須要將數組壓平展現,datatable之類的列表雖然強大,但看多了有點傻。改了下webix的源碼,以下:code

webix.CodeParser = {
    //converts a complex object into an object with primitives properties
    collapseNames:function(base, prefix, data){
        data = data || {};
        prefix = prefix || "";

        if(!base || typeof base != "object")
            return null;

        for(var prop in base){
            if(base[prop] && typeof base[prop] == "object" && !webix.isDate(base[prop]) && !webix.isArray(base[prop])){
                webix.CodeParser.collapseNames(base[prop], prefix+prop+".", data);
            } else if(base[prop] && typeof base[prop] == "object" && webix.isArray(base[prop])){
                for(var i=0;i<base[prop].length;i++){
                    webix.CodeParser.collapseNames(base[prop][i], prefix+prop+"["+i+"].", data);
                }
            } else {
                data[prefix+prop] = base[prop];
            }
        }
        return data;
    },
    //converts an object with primitive properties into an object with complex properties
    expandNames:function(base){
        var data = {},
            regex = /(\w+)\[(\d+)\]/,
            i, lastIndex, names, name, obj, prop;

        for(prop in base){
            names = prop.split(".");
            lastIndex = names.length-1;
            obj = data;
            for( i =0; i < lastIndex; i++ ){
                name = names[i];
                var match = regex.exec(name);

                if(match){
                    if(!obj[match[1]]){
                        obj[match[1]] = [];
                    }

                    while(obj[match[1]].length < 1+parseInt(match[2])){
                        obj[match[1]].push({});
                    }
                }else if(!obj[name]){
                    obj[name] = {};
                }

                obj = match? obj[match[1]][match[2]] : obj[name];
            }
            obj[names[lastIndex]] = base[prop];
        }

        return data;
    }
};

修改以後的問題是,不支持原來的樹形綁定,能夠經過既壓平展開、又保留原來的列表屬性來兼容2種綁定方式。orm

相關文章
相關標籤/搜索