我有很多地方使用淘汰数据绑定foreach循环。一个很好的例子是项目列表,右侧有一个单击按钮,表示“编辑”。我发现自己编写的代码如下所示:
<div data-bind="foreach: myListData">
... other divs ...
<button data-bind="click: $parent.editItem.bind($data)">View</button>
</div>
然后editItem
函数看起来像下面这样:
editItem: function (review, data) {
window.location = "/item/edit/" + review.Id();
},
我发现使用$parent
作为反模式,我也认为在同一行使用.bind
和只有淘汰的$data
是相当神秘的,特别是如果开发人员不熟悉淘汰赛。
是否有更好,更清晰的方法在淘汰赛foreach中编写父范围访问函数?
您可以将editItem函数放在每个Review上,也可以传入对其上定义了editItem函数的视图模型的引用。
我没有测试过以下样本,但它应该给你一个想法。
function Review(review, vm) {
var self = this;
review = review || {};
self.vm = vm;
self.Id = ko.observable(review.Id || 0);
// More properties if needed
}
// Add an editItem prototype to each Review
Review.prototype.editItem = function(review) {
// The bound item is passed in with the click binding
window.location = "/item/edit/" + review.Id();
// Or without using the item passed
// window.location = "/item/edit/" + this.Id();
// Or using the editItem function on the view model
// this.editItem = this.vm.editItem(review);
};
function ReviewViewModel() {
var self = this;
self.myListData = ko.observableArray([]);
// Add some sample data to the observable array
var myListData = [];
myListData.push(new Review({ Id: 1}, self));
myListData.push(new Review({ Id: 2}, self));
myListData.push(new Review({ Id: 3}, self));
myListData.push(new Review({ Id: 4}, self));
self.myListData(myListData);
// If you would rather have the editItem function on the view model
self.editItem = function(review) {
window.location = "/item/edit/" + review.Id();
};
}
// Markup
<button data-bind="click: editItem">View</button>