使用Knockout和Mapping插件时如何将错误附加到字段?

时间:2017-02-11 21:15:32

标签: knockout.js

我是一名Knockout.js新手,试图解决问题。我为我的用户提供了这个模型:

var UserModel = function(data)
{
    ko.mapping.fromJS(data, {}, this);

    // Other non-relevant stuff

    this.errors = ko.observableArray();

    this.save = function()
    {
        $.ajax({
            type: 'PUT',
            url: API+'user',
            data: ko.mapping.toJSON(this),
            contentType: 'application/json',
            context: this,
            success: function(data)
            {
                ko.mapping.fromJS(data, {}, this);
            },
            error: function(jqxhr, status, error)
            {
                if(jqxhr.responseJSON.errors)
                    this.errors(jqxhr.responseJSON.errors);
            },
        });
    };
}

当put失败时,errors会被填充,至少就我所见:

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

{
  "id": 2,
  "email": "alice@example.com",
  "name": "Alice",
  "roles": "login",
  // Other non-relevant stuff
  "errors": {
    "email": [
      "Invalid email domain."
    ],
    "name": [
      "Cannot be empty."
    ]
  }
}

但是,使用下面的模板,如何在错误所属的每个字段旁边显示这些错误?

我正在为用户使用的模板目前如下所示:

<script type="text/html" id="user-row">
    <tr spellcheck="false">
        <td>
            <div data-key="Name" data-bind="editable: editing, editableValue: name"></div>
        </td>
        <td>
            <div data-key="Email" data-bind="editable: editing, editableValue: email"></div>
        </td>
        <td>
            <div data-key="Roles" data-bind="editable: editing, editableValue: roles"></div>
        </td>
        <td>
            <a href="javascript:void(0)" data-bind="click: save">Save</a>
        </td>
    </tr>
</script>
  1. 如果没有密钥,如何绑定错误文本?
  2. 如何在每个div下按键“过滤”?

1 个答案:

答案 0 :(得分:1)

在您的代码this.errors中声明为observable array ,但根据您的JSON响应,您指定了对象

您可能会发现我经常使用的方法来扩展特定observable和可观察数组的功能。我只是用有用的方法(和/或甚至是计算值)扩展它们

this.errors = ko.observable();

// extend observable with a method that allows to get errors for specified field if they exist
this.errors.get = function(field){
    var errs = this.errors();
    return errs && errs[field] && errs[field].join(";");
};

// further in HTML under every div with editable binding:
<span class="error" data-bind="text: errors.get('email')"></span>