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則是雙層循環。數組
但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