集成json-editor小结


一、需求目的

目的:将复杂的json编辑可视化,让填写字段值更容易。

业务背景:业务系统中上下游的交互有时候是通过一段报文(比如大宝的网关和PAC的交互),有时候又是通过消息的机制来达成异步化(比如metaQ、精卫),而我想做的是根据场景方便的mock这个报文或者消息,并且这些报文或者消息有一些约定好的结构与字段。

工具库:github上排名非常靠前的json-editor


二、拆分需求

json-editor所做的就是根据你定义的有效的json schema,渲染出html form,而它本身所需要的依赖,none,only浏览器。

所以我从源码中剥离了这个例子:advanced.html,它符合我的需求是因为它这里有多个schema的切换Basic Person->Complex Person,而我就是有多种消息格式的schema。

本来以为一切就这么愉快地结束了。

但是用起来的时候发现,new一个editor时,它的startval是给定的:

// Initialize the editor
var editor = new JSONEditor(document.getElementById('editor_holder'),{
	// Enable fetching schemas via ajax
    ajax: true,
	......	    
	// Seed the form with a starting value
	startval: starting_value,
	......
});

而我期望的是对于不同的schema有不同的初始化值。


三、解决

第一步想到的就是对切换schema的select下拉框增加change事件监听,试了后发现不生效。查看了下原实现中select已绑定了change事件,并且实现中用e.preventDefault()来阻止事件往上冒泡了,所以才对我增加的事件监听不生效。

于是回到json-editor库本身,通过editor.editors查看对象下所有成员变量与方法,同时结合文档。发现editor提供了一个ready事件( If the ajax property is true and JSON Editor needs to fetch an external url, the api methods won’t be available immediately. Listen for the ready event before calling them.),于是我们可以把对select的监听插入到这个事件中。其中select元素没有分明的name或id,所以取到元素还花了些时间。

  editor.on('ready',function() {
    var editors = editor.editors;
    if (!editors) {
      return false;
    }

    var rowHolder = editor.editors['root']['row_holder'];
    var selectDom = rowHolder.querySelectorAll('.content > select');

    selectDom[0] && selectDom[0].addEventListener('change', function (e) {
      var _this = e.currentTarget;
      var option = (function () {
         var options = _this.childNodes;
         var aim = null;
         options.forEach(function (option, index) {
            if (option.selected) {
              aim = option;
              return true;
            }
         })
         return aim;
      }());

      if(_this.value === 'Complex Person')
        editor.setValue(starting_value_2);
    })
  });
crystal /
Published under (CC) BY-NC-SA in categories 前端  tagged with json-editor