6

我相信这对某人来说是一个简单的答案。我有以下视图模型:

@{
    var initialData = new JavaScriptSerializer().Serialize(Model);
}
var data = @Html.Raw(initialData);
function ViewModel(data) {
    var self = this;
    self.Name = ko.observable(data.Name);
    self.Items = ko.observableArray(data.Items);
    self.addItem = function() { self.Items.push(""); };
    self.removeItem = function(data) { self.Items.remove(data); }
}
$(document).ready(function() {ko.applyBindings(new ViewModel(data)); });

以及以下视图:

<div>
    Name: <span data-bind="text: Name"></span>
</div>
<div>
    Items: <button data-bind="click: addItem">Add Item</button>
</div>
<div>
    <table>
        <tbody data-bind="template: { name: 'itemTemplate', foreach: Items }"></tbody>
    </table>
</div>
<script type="text/html" id="itemTemplate">
    <tr>
        <td>
            <input data-bind="value: $data" />
            <a href="#" data-bind="click: function() {$parent.removeItem($data)}">Remove Item</a>
        </td>
    </tr>
</script>

一切似乎都正常工作,除了removeItem. 添加新行并在空的新行上单击“删除项目”时,所有新行都将随之删除。我查看了大量试图让它发挥作用的淘汰教程,我的方法似乎是一种有效的尝试,但显然......我一定遗漏了一些东西。有什么建议么?

4

1 回答 1

14

observableArray的remove函数循环遍历数组并删除与传递给它的值匹配的所有项。在您的情况下,您只是在处理字符串,它会看到所有新的(没有值)都将匹配“”。

有几种处理方法:

  • 您可以处理对象,而不仅仅是像{ value: ko.observable("") }. 然后,当您传递时,$data它只会删除与该对象引用匹配的实际项目。如果您的值是不可观察的并且是数据本身(不是属性),那么您的写入实际上不会返回到您的视图模型。

  • 如果这不适用于您的场景,那么您可以$index使用 splice 根据索引 ( ) 删除项目。

我可能会这样做:http: //jsfiddle.net/rniemeyer/N3JaW/

另请注意,event( clickis a wrapper to event) 绑定会将当前数据作为第一个参数传递给处理程序,因此您可以简化与click: $parent.removeItem.

更新:这里有几种方法可以控制您的对象如何转换为 JSON:

  • ko.toJSON将其第二个和第三个参数传递给JSON.stringify. 第二个参数让您运行一个函数来潜在地替换此处描述的值。这是一个示例,用于检查键是否为数字(数组项)并且它具有value属性。如果是这样,它只返回字符串而不是对象。 http://jsfiddle.net/rniemeyer/N3JaW/1/

  • 如果您对对象使用构造函数,则可以按照此处toJSON所述覆盖该函数。这是具有此功能的示例:http: //jsfiddle.net/rniemeyer/N3JaW/2/

  • 另一种可以使用的技术是维护一个具有“好”值的计算 observable。这是示例:http: //jsfiddle.net/rniemeyer/N3JaW/3/。在这个中Items是一个计算的 observable,它返回干净的值。 Items.asObjects包含您的值的对象版本。asObjects转换为 JSON 时,转换为 JSON时自然会丢弃该部分Items。如果您在转换为 JSON 时只需要这个“好”数组,那么其他选项对性能更好(它们仅在您要发送时计算)。

于 2012-08-30T16:26:43.773 回答