我对Knockout.js很新,我现在正面临一种情况,我不确定如何正确处理它。问题是:我收到了一堆我正在通过ajax检索的对象。结果有点像这样:
var Objects = [ { id: 0, name: "Foo", type: "A" },
{ id: 1, name: "Bar", type: "B" },
{ id: 1, name: "Bar", type: "A" }, ... ];
到目前为止我所做的(简化):
var ViewModel = function() {
var self = this;
self.objects = ko.observableArray(Objects);
};
现在我需要根据它们的“类型”在不同的列表中渲染这些对象。所以有一个类型为“A”的对象列表和一个类型为“B”的对象列表等(目前有五种类型,但将来可能会增加一些类型)。
我已经提出了这个(工作)解决方案:
var ViewModel = function() {
var self = this;
self.objects = ko.observableArray(Objects);
self.objectsA = ko.computed(function() {
return ko.utils.arrayFilter(self.objects(), function(item) {
return (item.type == 'A');
});
});
self.objectsB = ...
self.objectsC = ...
};
在我的实际观点中:
<h1>Type A</h1>
<ul class="typeA" data-bind="template: { name: 'object', foreach: objectsA }"></ul>
<h1>Type B</h1>
<ul class="typeB" data-bind="template: { name: 'object', foreach: objectsB }"></ul>
有没有更好的方法来解决这个问题?这很有效,但它有点难看,不是很有活力,而且包含很多重复。
答案 0 :(得分:5)
绑定在computed observable
内执行。这意味着如果您愿意,可以选择使用带参数而不是实际computed observable
的简单函数。
这意味着您可以将其简化为:
var ViewModel = function() {
var self = this;
self.objects = ko.observableArray(Objects);
self.filterByType = function(type) {
return ko.utils.arrayFilter(self.objects(), function(item) {
return (item.type === type);
});
};
};
然后,绑定它,如:
<h1>Type A</h1>
<ul class="typeA" data-bind="template: { name: 'object', foreach: filterByType('A') }"></ul>
<h1>Type B</h1>
<ul class="typeB" data-bind="template: { name: 'object', foreach: filterByType('B') }"></ul>
无论何时操作数组(添加/删除项目),您的UI都会立即更新。但是,如果您要动态编辑type
,那么type
将需要成为计算的observable更新的可观察对象(在您的原始方法中或以这种方式)。
答案 1 :(得分:1)
你可以让Knockout像这样进行过滤:
<h1>Type A</h1>
<ul class="typeA" data-bind="template: { name: 'object', foreach: objects }">
<li data-bind="if: type = 'A'"><!--whatever mark-up you wanted here--></li>
</ul>
然后对其他类型做同样的事情。或者,您甚至可以让ViewModel保存一组类型,并使用一个模板完成所有操作。
编辑:包括RP Niemeyer的答案,你可以这样做:
var ViewModel = function() {
var self = this;
self.objects = ko.observableArray(Objects);
self.types = ["A","B","C","D"];
self.filterByType = function(type) {
return ko.utils.arrayFilter(self.objects(), function(item) {
return (item.type === type);
});
};
};
<!-- ko foreach types -->
<h1> Type <span data-bind="text: $data"></h1>
<ul data-bind="{attr: {class = 'type' + $data}, template: { name: 'object', foreach: filterByType($data)}}"></ul>
<!-- /ko -->
现在添加类型E很简单,就像在类型数组中添加“E”一样。