2011-08-08 100 views
3

我遇到了一个问题,即删除可观察数组中的对象。我有一个removeItemFromQueue函数应该从队列中删除选定的对象。从observableArray中删除对象

This example表明,如果你添加了一堆的项目到队列中,然后取出一个,它消除了所有的人:

<h3>Items:</h3> 

<ul data-bind="template: {name:'itemsTemplate', foreach: items}"></ul> 

<h3>Queue:</h3> 

<ul data-bind="template: {name:'queueTemplate', foreach: queue}"></ul> 

<script id="itemsTemplate" type="text/x-jquery-tmpl"> 
    <li> 
     <a href="#">${$data.title}</a> by <a href="#">${$data.description}</a> 
     <button data-bind="click: function() {viewModel.removeItemFromPage($data);}">Remove From Page</button> 
     <button data-bind="click: function() {viewModel.addItemToQueue($data);}">Add To Queue</button> 
    </li> 
</script> 

<script id="queueTemplate" type="text/x-jquery-tmpl"> 
    <li> 
     <a href="#">${$data.title}</a> by <a href="#">${$data.description}</a> 
     <button data-bind="click: function() {viewModel.removeItemFromQueue($data);}">Remove From Queue</button> 
    </li> 
</script> 

这是JavaScript:

function Item(title, description) { 
    this.title = ko.observable(title); 
    this.description = ko.observable(description); 
} 

var viewModel = { 
    items: ko.observableArray([ 
     new Item("one", "one description") 
    ]), 
    queue: ko.observableArray([]), 
    addItemToQueue: function (item) { 
     this.queue.push(item); 
    }, 
    removeItemFromPage: function (item) { 
     this.items.remove(item); 
    }, 
    removeItemFromQueue: function (item) { 
     this.queue.remove(item); 
    } 
}; 

ko.applyBindings(viewModel); 

我发现this workaround使用ko.toJS(item)addItemToQueue功能:

<h3>Items:</h3> 

<ul data-bind="template: {name:'itemsTemplate', foreach: items}"></ul> 

<h3>Queue:</h3> 

<ul data-bind="template: {name:'queueTemplate', foreach: queue}"></ul> 

<script id="itemsTemplate" type="text/x-jquery-tmpl"> 
    <li> 
     <a href="#">${$data.title}</a> by <a href="#">${$data.description}</a> 
     <button data-bind="click: function() {viewModel.removeItemFromPage($data);}">Remove From Page</button> 
     <button data-bind="click: function() {viewModel.addItemToQueue($data);}">Add To Queue</button> 
    </li> 
</script> 

<script id="queueTemplate" type="text/x-jquery-tmpl"> 
    <li> 
     <a href="#">${$data.title}</a> by <a href="#">${$data.description}</a> 
     <button data-bind="click: function() {viewModel.removeItemFromQueue($data);}">Remove From Queue</button> 
    </li> 
</script> 

和这个Javascript:

function Item(title, description) { 
    this.title = ko.observable(title); 
    this.description = ko.observable(description); 
} 

var viewModel = { 
    items: ko.observableArray([ 
     new Item("one", "one description") 
    ]), 
    queue: ko.observableArray([]), 
    addItemToQueue: function (item) { 
     this.queue.push(ko.toJS(item)); 
    }, 
    removeItemFromPage: function (item) { 
     this.items.remove(item); 
    }, 
    removeItemFromQueue: function (item) { 
     this.queue.remove(item); 
    } 
}; 

ko.applyBindings(viewModel); 

是否有更简单的方法?

另外,这里的购物车示例看起来使用与我的第一个示例类似的代码,但不会遇到与删除项目相同的问题。我有点困惑。

+0

以下是购物车示例:http://knockoutjs.com/examples/cartEditor.html – horizens

回答

5

您遇到的问题是您要将相同的项目多次添加到您的队列数组中。

一个observableArray的remove函数将移除您传递给它的所有项目副本。

ko.toJS是一种获取数据干净副本的方法。但是,如果您需要它们,您将失去任何可观察到的事物。

否则,你可能想要做这样的事情:

this.queue.push(new Item(item.title(), item.description())或编写一个函数,将帮助您做出该项目的副本(传递一个项目,并返回一个新的项目)。