将复杂的错误对象映射到其关联的输入字段

时间:2017-12-28 15:30:56

标签: javascript jquery dictionary

假设我有以下字段

<input name="a" />
<input name="b[0]" />
<input name="b[1]" />
<input name="c[d]" />
<input name="c[e][f]" />

以及保存每个输入错误的以下对象

var errors = {
    a: 'error a ',     // a's error
    b: [
        'error b0',    // b[0]'s error
        'error b1'     // b[1]'s error
    ],
    c: {
        d: 'error cd ', // c[d]'s error
        e: {
            f: 'error cef'  // c[e][f]'s error
        }
    }
}

将每个错误映射到相关输入的有效方法是什么?

<input name="a" />
<div class="error">error a</div>
<input name="b[0]" />
<div class="error">error b0</div>
<!-- etc -->

我能想到这样做的唯一方法是循环输入name属性并使用eval来评估每个属性 - 这可能并不好。类似的东西:

$(':input').each(function () {
    var name = this.name.replace(/^([a-z0-9_\-]+)(.*)$/i, 'errors[$1]$2');
    var error = eval(name);

    $(this).after('<div class="error">' + error + '</div>');
});

有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以使用reduce()按当前输入元素的名称获取每个错误,然后使用after在当前输入元素之后添加它。

var errors = {"a":"error a ","b":["error b0","error b1"],"c":{"d":"error cd ","e":{"f":"error cef"}}}

function f(name, obj) {
  return name
    .split(/[[\]]{1,2}/)
    .filter(Boolean)
    .reduce((r, e, i, arr) => {
      return r[e] || (r[e] = arr[i + 1] ? {} : '')
    }, obj)
}

$("input").each(function() {
  let error = f($(this).attr('name'), errors)
  if(error.length) $(this).after(`<div class="error">${error}</div>`)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input name="a" />
<input name="b[0]" />
<input name="b[1]" />
<input name="c[d]" />
<input name="c[e][f]" />