KnockoutJS:设置 optionValue 打破“与”绑定

Posted

技术标签:

【中文标题】KnockoutJS:设置 optionValue 打破“与”绑定【英文标题】:KnockoutJS: Setting optionValue breaks "with" binding 【发布时间】:2014-11-24 08:00:19 【问题描述】:

我想知道是否有人知道为什么这段代码会被破坏。当我删除返回 productID 的函数时,tbody data-bind with: chosenProduct 可以正常工作,但将函数保留在中会导致 data-bind "value: marketName" 抛出一个错误,指出 "Uncaught ReferenceError: Uncaught ReferenceError: Unable to process binding "value: function ()return marketName " Message: marketName is not defined "。 这让我觉得由于某种原因chosenProduct 没有被设置为选择时的值。

html

<table>
    <tr><td><label>Product Name</label></td><td><select id="productSelect" data-bind="options: products, optionsCaption: 'Choose Product',optionsValue: function(i) return i.productID , optionsText:'productName', value: chosenProduct, valueUpdate: 'keyup'"></select></td></tr>
    <tbody data-bind="with: chosenProduct">
        <tr><td><label>Market</label></td><td><input type="text" readonly data-bind="value: marketName"></td></tr>
        <tr><td><label>Client</label></td><td><input type="text" readonly data-bind="value: clientName"></td></tr>
    </tbody>
</table>

javascript

this.products = /* ajax call returns array of product objects*/;
chosenProduct = ko.observable();
    resetProduct = function()  this.chosenProduct(null);;

一个产品对象:

productID: 1, marketName: "Test", clientName: "Client1"

【问题讨论】:

@haim770 selectedProduct 由“value: selectedProduct”数据绑定设置。当用户从选择框中选择一个项目时,具有所选属性的对象将成为“chosenProduct”。 @haim770 扩展我之前的评论:通过使 selectedProduct 充当可观察对象,它允许双向绑定。它可以由用户选择一个选择选项来设置(如我之前的评论中提到的)或由 Javascript 中的函数设置。 看我的回答。淘汰赛最好让实际产品对象为chosenProduct。使用ChosenProductID,您可以读取所选的 ID,如果您查看 writable computed 文档,您可以对其进行调整,以便在使用 ID 编写时,它会查看您的产品列表以将正确的设置为chosenProduct 【参考方案1】:

这是您对optionsValue setting的使用。

通过使用它,您是在告诉 knockout 将被选择事物的实际值设置为产品 ID。这只是一个数字,没有marketNameclientName 属性。解决方案是将其移除。 Knockout 非常适合以这种方式选择事物 - 如果您需要在其他地方选择产品的实际 ID,我建议在您的视图模型上创建一个额外的属性,例如:

this.ChosenProductID = ko.computed(function() 
    if (this.chosenProduct() != null)
        return this.chosenProduct().productID;

    return -1;
, this);

【讨论】:

好的,我想我明白了。我最初添加 optionValue 是因为我想稍后用 jQuery 调用它。最初,每个选项的 HTML 都只有一个空值属性。您认为使用 Knockout 提供的 optionsAfterRender 回调添加值可以让我同时满足这两个要求吗? 不 - 将所有内容都保留在淘汰赛中,并且几乎忽略您在 html 中看到的任何内容。请参阅我对原始帖子的其他评论,关于计算的 observables 以仅使用 ID 设置所选产品。文档中的示例应该可以帮助您进行 我有另一个想法 - 我将发布一个单独的答案,因为它来自另一种方法 - 给我 2 分钟...【参考方案2】:

如果您需要保留 optionsValue 绑定,以便 chosenProduct 纯粹是一个可读取/可写的 ID,因此您可以在 javascript 的其他位置设置它,我的其他答案的替代方法是创建一个 computed observable仅显示当前产品。然后可以在模板绑定中使用它:

this.chosenProductObject = ko.computed(function() 
    for (x = 0; x < this.products.length; x++)
        if (this.products[x].productID == this.chosenProduct())
            return this.products[x];
    return null;
, this);

对您的 html 进行微调:

<tbody data-bind="with: chosenProductObject">
    <!-- as before -->
</tbody>

【讨论】:

注意this 在淘汰赛中处理这类结构时指的是什么 - 链接文档页面上有关于如何设置它的信息。它会因您构建视图模型的方式而异。 谢谢,我得看看计算出的 observables。

以上是关于KnockoutJS:设置 optionValue 打破“与”绑定的主要内容,如果未能解决你的问题,请参考以下文章

使用 Knockoutjs 获取设置值属性

KnockoutJS 设置 jQuery Mobile 滑块的最大选项

knockoutjs 根据值有条件地设置图像 src

knockoutjs 经验总结

KnockoutJS observable 未在屏幕上更新

KnockoutJs:knockoutJs 上可用的 Event 类型都有哪些