从observableArray- knockoutjs中删除

时间:2012-08-30 16:02:24

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

我相信这对某些人来说是一个简单的答案。我有以下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之外,一切似乎都能正常工作。添加新行并在空的新行上单击“删除项”时,将删除所有新行。我看了很多淘汰教程试图让这个工作,我的方法似乎是一个有效的尝试,但显然......我必须遗漏一些东西。有什么建议吗?

1 个答案:

答案 0 :(得分:14)

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

有几种方法可以处理它:

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

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

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

另请注意,eventclickevent)包装器的绑定将当前数据作为处理程序的第一个参数传递,因此您可以简化绑定到{ {1}}。

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

  • click: $parent.removeItem将其第二和第三个参数传递给ko.toJSON。第二个arg让你运行一个函数来替换here所描述的值。下面是一个示例,它检查密钥是否为数字(数组项)并且具有JSON.stringify属性。如果是这样,它只返回字符串而不是对象。 http://jsfiddle.net/rniemeyer/N3JaW/1/

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

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