【问题标题】:Knockout - How can I bind an observable by the element's ID?Knockout - 如何通过元素的 ID 绑定 observable?
【发布时间】:2012-11-22 14:59:51
【问题描述】:

我正在构建一种机制来自动在表单字段中显示验证消息,并想讨论这个问题。

我有一个带有错误消息及其各自属性的可观察数组。

如何将可观察数组的元素绑定到其各自的表单字段?

observable 具有以下数据(即):

messages = ko.observableArray();
- Property: Reference, Message: Already exists a product with this reference.
- Property: Name, Message: The product's name is mandatory.
- Property: Bar Code, Message: The Bars Code does not matches the EAN13 format.
- ...

我的表单字段的 ID 与数组中的属性名称相同:

        <div class="s13">
            <label for="Reference">Reference</label>
            <input class="text-box single-line" id="Reference" name="Reference" type="text" value="" data-bind="value: selected().Reference" />
            <span id="vReference"></span>
        </div>

        <div class="s13">
            <label for="Name">Name</label>
            <input class="text-box single-line" id="Name" name="Name" type="text" value="" data-bind="value: selected().Name" />
            <span id="vName"></span>
        </div>

        <div class="s13">
            <label for="BarCode">Bars Code (EAN13)</label>
            <input class="text-box single-line" id="BarCode" name="BarCode" type="text" value="" data-bind="value: selected().BarCode" />
            <span id="vBarCode"></span>
        </div>

我是 Knockout.js 的新手,但我认为我需要使用“计算的 observable”,它会为每个跨度返回相应的消息。

你说什么?

/// 更新 ////////////////////////////////// ////////////

产品视图模型:

function mainmodel(baseUri) {

var m = this;
    m.baseUri = baseUri;

/// PRODUCTS VIEW MODEL ******************************************* *

    m.products = new function () {

        var p = this;
            p.baseUri = baseUri;
            p.items = ko.observableArray();
            p.selected = ko.observable();
            p.messages = ko.observableArray([]);

产品加载中

        /// LIST
            p.list = function () {
                $.getJSON(p.baseUri + "/list" + "?page=" + p.currentpage(), p.items);
            }

产品创建(加载验证消息的位置)

        /// CREATE
            p.create = function (formElement) {
                //$.post(p.baseUri + "/create", $(formElement).serialize(), null, "json")
                $.ajax({
                    type: 'POST',
                    url: p.baseUri + "/create",
                    data: $(formElement).serialize(),
                    success: null,
                    dataType: "json",
                    statusCode: {
                        400: function (o) {
                            p.messages($.parseJSON(o.responseText));
                        }
                    }
                });
            }

运行此程序,p.messages 包含每个产品属性的验证消息。

【问题讨论】:

  • 这些验证消息是否通过 AJAX 请求从服务器返回?
  • 是的,例如,当客户端调用我的 Web api 中的 Create 方法时,它会返回一个 HTTP 响应和一个包含所有验证消息的对象。然后我处理填充 observableArray 的消息。
  • 这不是 jquery 的工作吗?类似于: ko.utils.arrayForEach(messages, function (message) { $("#v" + message.Property).html(message.Message); }
  • 使用 Knockout 时,这样做超出了正常流程。你真的想让你的视图模型代表你的视图绑定的状态。您在 view-viewmodel 之外拥有的代码越多,维护起来就越困难。所以,你可以选择这样做,但这不是使用 Knockout 的“正常”方式。
  • 我明白了,你是对的。我会保持这种方式来完成这个 sprint,但我很快就会改变。

标签: knockout.js validation


【解决方案1】:

我认为有几种方法可以用于这个。如果您从对服务器的请求中接收到这些验证消息,那么您可以遍历它们并根据结果直接填充 observables。

一个很好的方法是创建一个“sub” observable 来保存验证消息,例如:

this.myObservable = ko.observable();
this.myObservable.validationMessage = ko.observable();

现在您可以绑定myObservablemyObservable.validationMessage

因此,如果您收到返回的消息数组,您可以遍历它们并应用如下消息:

        var messages = [
            { Property: "Reference", Message: "Can't find a reference to this reference" },
            { Property: "Name", Message: "Pick a better name" },
            { Property: "BarCode", Message: "Not a valid code" }
        ];

        //apply messages to each observable
        ko.utils.arrayForEach(messages, function(message) {
            if (ko.isObservable(self[message.Property])) {
               self[message.Property].error(message.Message);  
            }
        });

我不知道您的应用程序流程,但您可能想先清除错误。

这是一个示例:http://jsfiddle.net/rniemeyer/mk2Ed/

这是一个使用计算出的 observables 的替代方案(第一个会稍微高效一些):http://jsfiddle.net/rniemeyer/R6mL8/

【讨论】:

  • 我现在就试试这个。我希望我可以设置 .error 而不声明它。因为我没有声明我的 Product 对象。
猜你喜欢
  • 2012-03-16
  • 2015-08-15
  • 2015-04-05
  • 2010-11-25
  • 2014-06-09
  • 2014-11-27
  • 2017-01-10
  • 2015-03-28
  • 2021-05-18
相关资源
最近更新 更多