【问题标题】:remove from observableArray- knockoutjs从 observableArray-knockoutjs 中移除
【发布时间】:2012-08-25 10:12:39
【问题描述】:

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

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

【问题讨论】:

    标签: javascript asp.net-mvc knockout.js


    【解决方案1】:

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

    有几种处理方法:

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

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

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

    还要注意eventclickevent 的包装器)绑定会将当前数据作为第一个参数传递给处理程序,因此您可以简化与click: $parent.removeItem 的绑定。

    更新:您可以通过以下几种方式控制对象转换为 JSON 的方式:

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

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

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

    【讨论】:

    • 我真的很喜欢你在 jsfiddle 上的方法,但我没有提到我需要将此模型发布回服务器。这意味着Items 需要是一个字符串[]。 Soo 我猜这意味着我应该走 $index 路线,对吗?
    • 不一定。有多种方法可以确保 JSON 输出恢复到您想要的状态。我会为答案提供一些信息。
    • 如果可以的话,我会给你两个。很有帮助的答案。
    • @RPNiemeyer 再次救援!
    猜你喜欢
    • 2012-07-12
    • 2013-10-23
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多