Source: tool/JsonSchemaEditor.js


//
Rsd.define('Rsd.tool.JsonSchemaEditor', {
    extend: 'Rsd.zen.dialog.ListDialog',
    requires: [
        'Rsd.control.Grid',
        'Rsd.form.Label',
        'Rsd.form.Button'
    ],
    xtype: 'schema-editor', 
    readOnly:false,    
    layout: 'vbox',
    width:'90%',
    height:'90%',
    autoLoad:true,
    toolbar:null,
    /**
     * 复杂属性显示模式:full:完全数据,simple:简单
     */
    model:'simple',
    formHeight:'100%',
    formWidth:800,
    formPosition:'right',
    titleField:'$id',
    formTitle:"Schema详细信息:{{=$id}}",
    /**
     * https://json-schema.org/understanding-json-schema/
     */
    allFields:
    [
        {
            name:"$id",
            label:'     键值',
            readOnly:true,
            width:'70%',
            ctrlStyle:{border:'0px',borderBottom:'1px grey solid'}
        }, 
        {
            name:"type",
            label:"     数据类型",
            readOnly:true,
            width:'20%',
            ctrlStyle:{border:'0px',borderBottom:'1px grey solid'}
        },
        {
            name:"$ref",
            label:"     引用",
            //readOnly:true,
            width:'90%',
            ctrlStyle:{border:'0px',borderBottom:'1px grey solid'}
        },
        //$defs
        {
            name:"dependencies",
            label:"     依赖",
            width:'90%',
            ctrlStyle:{border:'0px',borderBottom:'1px grey solid'}
        },
        {height:15,width:"100%",style:{backgroundImage:"linear-gradient(#eee,#fff"}},
        {
            name:"title",
            label:'     数据名称',
            width:'50%'
        },
        {
            width:'40%'
        },
        //UI 交互 录入控件
        {
            name:"xtype",//录入控件
            label:"     录入控件",
            for:"string",
            xtype:"combobox",
            dataSource:["text","number","date","image","combobox","combbox-enum"],
            width:'40%'
        },
         //UI 交互 录入控件
         {
            name:"xtype",//录入控件
            label:"     录入控件",
            for:"array",
            xtype:"combobox",
            dataSource:["list","grid","tree"],
            width:'40%'
        },
        //UI 交互 录入控件
        {
            name:"xtype",//录入控件
            label:"     录入控件",
            for:"object",
            xtype:"combobox",
            dataSource:["modelForm","JsonForm"],
            width:'40%'
        },
        //UI 视觉
        {name:"height",label:'     编辑框高度',width:'25%'},
        {name:"width",label:"     编辑框宽度",width:'25%'},  
        {name:'labelStyle',label:"     标签样式"},
        {name:'ctrlStyle',label:"     控件样式"},
        //UI 交互 数据源
        {
            //关联录入控件的数据源
            name:"dstype",//录入控件
            label:"     数  据  源",
            for:"string",
            xtype:"combobox",
            dataSource:[
                {text:"常用文字",value:'text'},
                {text:"图片",value:'image'},
                {text:"链接",value:'link'},
                {text:"枚举",value:'enum'},
                {text:"其他数据",value:"other"}
            ],
            width:'45%',
            onchange:'dstype_change'
        }, 
        {
            name:"enum",label:"         枚 &nbsp举",
            for:"string",width:'45%',xtype:'combobox'
        },  
        {name:"description",label:"     录入提示",width:'90%'},
        {name:"examples",label:"     示例数据",width:'90%',xtype:'json'},
       
        //"readOnly" 
        //"writeOnly"
     
        //string
        {name:"minLength",label:"     最小长度",for:"string",width:'30%'},
        {name:"maxLength",label:"     最大长度",for:"string",width:'30%'}, 
        {name:"default",label:"     默认值",for:"string",width:'30%'},
        {name:"pattern",label:"  正则表达式",for:"string"},
        {name:"format",label:"   格式化表达式",for:"string"}, 

        //number
        {name:"multipleOf",label:"   是该值的倍数",for:"number",width:'20%'},
        {name:"maximum",label:"   最大值",for:"number",width:'20%'},
        {name:"exclusiveMaximum",label:"   不包含最大值",for:"number",width:'20%'},
        {name:"minimum",label:"   最小值",for:"number",width:'20%'},
        {name:"exclusiveMinimum",label:"   不包含最小值",for:"number",width:'20%'},
        {name:"default",label:"   默认值",for:"number",width:'20%'},

         //对象类型 约束
        //{name:"properties",label:"属性",for:"object"},
        //patternProperties 属性名通过正则表达式匹配
        {name:"minProperties",label:"   最少属性成员",for:"object",width:'20%'},
        {name:"maxProperties",label:"   最多属性成员",for:"object",width:'20%'},
        {name:"required",label:"   必填属性",for:"object",width:'50%'}, 
        {name:"additionalProperties",label:"   其他属性Schema",for:"object",width:'90%',tip:'对象属性除properties设定schema之外,允许的其他schema'},

        //数组类型 约束
        //{name:"items",label:"数组元素Schema",for:"array"}, 
        {name:"minItems",label:"   数组最小长度",for:"array",width:'30%'},
        {name:"maxItems",label:"   数组最大长度",for:"array",width:'30%'},
        {name:"uniqueItems",label:"   数组中元素唯一",for:"array",width:'30%'},
        {name:"additionalItems",label:"   其他数组元素Schema",for:"array",width:'90%',tip:'数组元素除items设定schema之外,允许的其他schema'},

        //通用约束
        {height:15,width:"100%",style:{backgroundImage:"linear-gradient(#eee,#fff"}},
        {name:"allOf",label:"  必须满所有子Schema",width:'90%'},
        {name:"anyOf",label:"  满足其中一个或多个子Schema",width:'90%'},
        {name:"oneOf",label:"  满足其中一个子Schema",width:'90%'},
        {name:"not",label:"  不允许满足的子Schema",width:'90%'}
    ],
    /**
     * 
     */
    gridColumns:[
        {
            xtype:'template',
            text:'名称(代码)',
            align:'left',
            dataIndex:'title',
            width:'20%',
            format:'title_format',
            nobr:true
        },
        {
            dataIndex:"type",
            text: "类型",
            nobr:true,
            xtype:'enum',
            enum:[
                {code:'object',text:'Json对象',color:'blue'},
                {code:'array',text:'Json数组',color:'green'},
                {code:'string',text:'字符',color:'black'},
                {code:'number',text:'数字',color:'black'},
                {code:'date',text:'日期',color:'black'}
            ]
        }, 
        {xtype:'bool',dataIndex:"required",text: "必填"},
        {dataIndex:"default",text: "默认值"},
        {
            xtype:'template',
            align:'left',
            dataIndex:"examples",
            text: "示例数据",
            formatString:'描述:{{=description}}<br>示例:{{=examples}}',
            maxLength:'30%'
        },
        {
            xtype:'template',
            text:'编辑框大小',
            tip:'表单编辑时,编辑框大小',
            nobr:true,
            formatString:'{{=height}} * {{=width}}'
            
        }
    ], 
    buttons:[{text:'保 存',label:false}],
    /**
    * 通过rowdblclick实现自定义编辑
    */
    //rowdblclick:'schema_rowdblclick', 
    /*
     * */
    constructor: function JsonSchemaEditor(config) {

        config = config || {};
        this.apply(config);  
    },
    /**
     * 
     * @param {*} schema 
     */
    load:function load(schema)
    {
        this.data = (schema||this.data||{}); 
        this.data.height = this.data.height ||'auto';
        this.data.width = this.data.width ||'auto';
        this.data.childIndex = 0;
        var _list = [this.data]; 
        //递归
        var _fn = function(_properties,childIndex)
        {
            for (var i in _properties) {
                var p = _properties[i];
                p.title = p.title;
                p.height = p.height ||'auto';
                p.width = p.width ||'auto';
                p.childIndex = childIndex;
                _list.push(p);

                if(p.type=='object')
                { 
                    _fn(p.properties,childIndex+1);
                    continue;
                }
                if(p.type =='array')
                {
                    if(Rsd.isArray(p.items))
                    { 
                        _fn(p.items,childIndex+1);
                    }
                    else
                    {
                        _fn(p.items.properties,childIndex+1);
                    }
                    continue;
                }   
            }
        }
        //入口
        _fn(this.data.properties,1);
        //加载数据
        this.callParent(_list);
    },
    /**
     * 
     * @param {*} sender 
     * @param {*} row 
     */
    title_format:function title_format(row)
    { 
        var list = [Rsd.blankspace(row["childIndex"]*4)];
        list.push(Rsd.text(row["title"]+'('+row["$id"]+')'));
        if(row["type"] == 'array' && Rsd.isObject(row["items"]))
        {
            list.push(Rsd.text('[结构相同]',{color:'red'},'数组元素使用相同Schema'))
        } 
        return list;
    },
    /**
     * 
     * @param {*} row 
     * @param {*} readOnly 
     */
    showItem:function showItem(row,readOnly)
    {
        this.formFields = [];
        for(var i in this.allFields)
        {
            var f = this.allFields[i];
            if(!f.for || row['type'] == f.for)
            {
                this.formFields.push(f);
            } 
        }
        this.callParent(row,readOnly);
    },
    /**
     * 
     * @param {*} sender 
     * @param {*} e 
     */
    dstype_change:function(sender,e)
    {
        var form = sender.parent;
        var enumCombobox = form.getItemByName('enum');
        enumCombobox.setDisabled(sender.getValue()!='enum');
        
    },
    /**
     * 
     * @param {*} data 
     */
    saveHandler:function saveHandler(data)
    {
        //schema存储
        console.log(data);
    } 

},function (type) {

});