我有一个装满文件的阵列。此文档包含一些类别,并按类别排序。对于每个类别,我希望有一个标题,如: - 运动 --- SportDocument 1 --- SportDocument 2 --- SportDocument 3 - 锦标赛 --- TournamentDocument 1 --- TournamentDocument 2 --- TournamentDocument 3
所以类别" Sport"和#"锦标赛"是标题。
我的问题是,我不知道如何使用此标题创建新的Div以获得列表。
我当前的代码
var DocumentRow = function (documentLine) {
var self = this;
// getting name and ID of the document
self.Name = ko.observable(documentLine.Name);
self.DocumentId = ko.observable(documentLine.DocumentId);
// creating downloadLink
self.DocumentLink = ko.computed(function () {
return "someUrlPath/read/import/" + self.DocumentId();
});
}
GetCustomerDocuments(data.SomeID)
.done(function (data) {
// Reset Documents from Previous View
self.documentLines([]);
// Only mapping when it has some data
if (data !== null && data !== undefined && data.length > 0) {
// loop trought the arry
self.documentLines(data.map(function (doc) {
return new DocumentRow(doc);
}));
}
})

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="foreach: documentLines">
<div class="importDocument">
<a data-bind="attr: {href: DocumentLink}, target:'_blank'">
<span data-bind="target:'_blank'">
<img src="../images/pdf.png" title="Document" />
</span>
<span data-bind="text: Name, target:'_blank'" title="Document"></span>
</a>
</div>
</div>
&#13;
答案 0 :(得分:1)
生成易于读取的数据绑定的简洁解决方案是创建ko.computed
,为您的数据添加分组图层。你要创建这个结构:
计算使用您的documentLines
数组作为起点,为其遇到的每个唯一Category
创建一个组,并将与此类别匹配的文档推送到该组。
您尚未显示实际的Category
属性,因此我假设它是每个documentRow
内的字符串属性。
下面的代码显示了分组计算机如何工作的示例。查看评论以获得有关正在发生的事情的解释。通过属性对对象进行分组是常见的事情,stackoverflow上应该有许多其他示例,向您展示如何进行操作。这更多关于淘汰赛如何运作:
var VM = function() {
var self = this;
// This is our data source
self.documentRows = ko.observableArray([]);
// This injects a group layer and will be used in our foreach:
self.docGroups = ko.pureComputed(function() {
// This creates a subscription that makes sure the object is updated
// every time the documentRows are updated
var rows = self.documentRows();
// Grouping logic:
// create an object of: { "CategoryName": [ /* documentRows*/ ] }
var categoryMap = rows.reduce(function(map, row) {
var category = row.Category;
map[category] = map[category] || [];
map[category].push(row);
return map;
}, {});
// Transform to object and sort by name
return Object.keys(categoryMap)
.map(function(k) {
return { name: k, rows: categoryMap[k] }
})
.sort(function(c1, c2) {
return c1.name.localeCompare(c2.name);
});
});
}
var vm = new VM();
ko.applyBindings(vm);
vm.documentRows.push({Category: "Cat1", Text: "The First Document"});
vm.documentRows.push({Category: "Cat2", Text: "The Second Document"});
vm.documentRows.push({Category: "Cat2", Text: "The Second 2nd Document"});
vm.documentRows.push({Category: "Another category", Text: "The Third Document"});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h2>Categories:</h2>
<ul data-bind="foreach: docGroups">
<li>
<h3 data-bind="text: name"></h3>
<ul data-bind="foreach: rows">
<li data-bind="text: Text"></li>
</ul>
</li>
</ul>
其他方法:
如果您不想要嵌套结构,您还可以创建一个包含两种类型对象的平面列表:文档和组。您必须使用if
或template
绑定来确定您希望如何呈现它。
如果您确定您的数据是按分组属性排序的,那么可以通过检查$parent.documentLines()[$index() - 1].Category === $data.Category
来创建视图中是否需要类别标签的逻辑,但我强烈反对这个建议......