并排迭代两个对象

时间:2014-05-12 17:12:53

标签: javascript object

我有一个架构和一个数据对象。使用模式我需要创建一个表单,并使用数据对象我需要填充它。什么是最好的方法呢?

示例:

var schema = {
    object: {
        someData: {
           type: "String",
           required: "true"
        },
        name: {
          type: "String",
          required: "false"
       }
   }
}

var data = {
   object: {
       someData: "foo",
       name: "John"
   }
}

由此我需要生成类似这样的东西

<form>
<fieldset><legend>object</legend>
<input type="text" name="someData" value="foo">
<input type="text" name="name" value="John">
</fieldset>
</form>

我已经想到了实现这一目标的几种方法,但我认为我过于复杂了。必须有一个更简单的方法,对吧?

有两个捕获:Schema没有修复,它可以改变。另一个是某些数据类型本身就是对象。

编辑:我过分简化了这个问题。这是最简单的情况,但在我的特定情况下,我有更复杂的数据对象和模式,它们会发生变化,而且我需要在用户编辑内容后从表单重新创建数据对象。我编辑了数据以考虑到这一点。

5 个答案:

答案 0 :(得分:1)

在我看来,你能做的最简单的事情是循环数据对象的键,然后立即从模式中获取每个类型。您还可以使用为每种类型创建输入的方法添加一个对象,以避免出现巨大的switch语句。

var controlFactory = {
  'String': function (name, value) {
     return '<input type="text" name="'+name+'" value="'+value+'">';
   }
}

var info, value;
for (var name in data) {
  value = data[name];
  info = schema[name];

  if (info && controlFactory[info.type]) {
     // create form field from factory
  }
}

答案 1 :(得分:1)

创建一个接受模式和数据的函数,然后在该函数中创建表单。这是一个基本的例子。在生产中,您可以在函数中使用switch语句来表示不同的数据类型。

小提琴: http://jsfiddle.net/CR58L/8/

var FormBuilder = function(schema, data) {
    this.schema = schema
    this.data = data

    this.form = document.createElement("form")
    this.inputs = []

    this.form.addEventListener("submit", this)
    this.createInputs()
}

FormBuilder.prototype = {
    "createElement": function(field, data, fieldset) {
        var fieldset = fieldset || false,
            element, value

        switch ( data.type ) {
            case "String":
                element = document.createElement("input")
                element.setAttribute("name", field)

                value = (fieldset ? this.data[fieldset][field] : this.data[field]) || ""
                element.setAttribute("value", value)

                if ( data.required === "true" ) element.setAttribute("required", "required")
                if ( fieldset ) element.setAttribute("data-fieldset", fieldset)
                break;
        }

        this.inputs.push(element)
        return element
    },    
    "createInputs": function() {
        var element, fieldset

        for ( var field in this.schema ) {
            if ( this.schema[field]["type"] ) {
                element = this.createElement(field, this.schema[field])
                this.form.appendChild(element)
            } else {
                fieldset = document.createElement("fieldset")
                legend = document.createElement("legend")
                legend.innerHTML = field
                fieldset.appendChild(legend)

                for ( var input in this.schema[field] ) {
                    element = this.createElement(input, this.schema[field][input], field)
                    fieldset.appendChild(element)
                }

                this.form.appendChild(fieldset)
            }
        }

        element = document.createElement("button")
        element.setAttribute("type", "submit")
        element.innerHTML = "Submit"

        this.form.appendChild(element)
    },
    "handleEvent": function(e) {
        e.preventDefault()
        var element, _dataRef, fieldset

        for ( var input in this.inputs ) {
            element = this.inputs[input]
            fieldset = element.getAttribute("data-fieldset")

            _dataRef = fieldset ? this.data[fieldset] : this.data
            _dataRef[element.getAttribute("name")] = element.value
        }

        console.log(data)
    }
}

var fb = new FormBuilder(schema, data)
document.getElementById("container").appendChild(fb.form)

答案 2 :(得分:1)

如果您使用的是JQuery,可以尝试这样的方法:

for(var key in schema){
    if(schema.hasOwnProperty(key)){
        var $field = $('<input>').attr({
            type : 'text',
            name : key,
            value : data[key]
        });
        $body.append($field);
    }
}

这里是JSFiddle:http://jsfiddle.net/L8QQm/1/

答案 3 :(得分:1)

使用ECMA5方法可以做到这一点。

HTML

<form id="myForm"></form>

的Javascript

var schema = {
        object: {
            someData: {
                type: "String",
                required: "true"
            },
            name: {
                type: "String",
                required: "false"
            }
        }
    },
    data = {
        object: {
            someData: "foo",
            name: "John"
        }
    },
    myForm = document.getElementById('myForm');

Object.keys(schema).forEach(function (legendText) {
    var fieldsetGroup = this[legendText],
        fieldset = document.createElement('fieldset'),
        legend = document.createElement('legend');

    legend.appendChild(document.createTextNode(legendText));
    fieldset.appendChild(legend);
    Object.keys(fieldsetGroup).forEach(function (elementName) {
        var attributes = this[elementName],
            input = document.createElement('input');

        input.name = elementName;
        input.value = data[legendText][elementName];
        Object.keys(attributes).forEach(function (attributeName) {
            var value = this[attributeName];

            if (attributeName === 'required') {
                value = (value === 'true');
            } else if (attributeName === 'type') {
                if (value === 'String') {
                    value = 'text';
                } else {
                    // whatever else
                    value = 'text';
                }
            }

            input[attributeName] = value;
            fieldset.appendChild(input);
        }, attributes);
    }, fieldsetGroup);

    myForm.appendChild(fieldset);
}, schema);

jsFiddle

答案 4 :(得分:0)

一块蛋糕!

// Define the variables, like you want
var schema = {
  someData: {
    type: "String",
    required: "true"
  },
  name: {
    type: "String",
    required: "false"
  }
};

var data = {
  someData: "foo",
  name: "John"
};

//n for name
for (var n in data) {
  //good practice to check
  if (data.hasOwnProperty(n) && schema.hasOwnProperty(n)) {
    var t = schema[n].type; //t for type
    var v = data[n];  //v for value
    console.log('<input type="' + t + '" name="' + n + '" value="' + v + '">');
  }
}

希望有所帮助:)