c# - GroupBy, Filtering in knockout.js
问题描述
How can i groupby, and filter in a table using knockout.js. I also try to expand and collapse row and this the code that I am somewhat successfull).
This is my distinc function, note at the moment it seem to only work on one data element ( i would like it to have it in the future to be distinct on a property for an object.
ko.observableArray.fn.distinct = function (prop) {
var target = this;
target.index = {};
target.index[prop] = ko.observable({});
ko.computed(function () {
//rebuild index
var propIndex = {};
ko.utils.arrayForEach(target(), function (item) {
var key = ko.utils.unwrapObservable(item[prop]);
if (key) {
propIndex[key] = propIndex[key] || [];
propIndex[key].push(item);
}
});
target.index[prop](propIndex);
});
return target;
};
This is my current object function
course(_id, _courseCode, _courseTitle, _courseCampus) {
var self = this;
this.id = ko.observable(_id);
this.courseCode = ko.observable(_courseCode);
this.courseTitle = ko.observable(_courseTitle);
this.coursecampus = ko.observable(_courseCampus);
}
There is my viewmodel
function ViewModel() {
var self = this;
this.courses = ko.observableArray().distinct('courseCode');
this.gpCourseCode = ko.observableArray();
this.mutated = ko.observableArray();
this.switchMutated = function (code) {
if (self.mutated.indexOf(code) > -1) {
self.mutated.push(code);
}
else {
self.mutated.remove(code);
}
};
this.switchText = function (code) {
if (self.mutated.indexOf(code) > -1) {
return "-"
}
else {
return "+"
}
};
self.gpCourseCode.push("MATH1030");
self.gpCourseCode.push("MATH1006");
self.gpCourseCode.push("MATH1046");
self.courses.push(new course("1", "MATH1030", "Calculus", "city1"));
self.courses.push(new course("2", "MATH1030", "Calculus", "city2"));
self.courses.push(new course("3", "MATH1030", "Calculus", "city3"));
self.courses.push(new course("4", "MATH1006", "Linear algebra", "city1"));
self.courses.push(new course("5", "MATH1046", "Discrete Math", "city2"));
self.courses.push(new course("6", "MATH1006", "Linear algebra", "city2"));
self.courses.push(new course("7", "MATH1046", "Discrete Math", "city1"));
this.searchCode = ko.observable("");
self.filteredRecords = ko.computed(function () {
return ko.utils.arrayFilter(self.gpCourseCode(), function (rec) {
return (
(self.searchCode().length == 0 || rec.toLowerCase().indexOf(self.searchCode().toLowerCase()) >= 0)
)
});
});
}
This is my html
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Course Code</th>
<th>Course Title</th>
<th>Course Campus</th>
</tr>
<tr>
<th><input data-bind="value: searchCode" placeholder="Course Code" /></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: filteredRecords">
<tr class="table-dark">
<td><span data-bind="text: $data"></span></td>
<td><span></span></td>
<td></td>
<td class="text-right">
<button class="btn btn-secondary" data-bind="click: $root.switchMutated($data), text: $root.switchText($data)"></button>
</td>
</tr>
<!-- ko foreach: $root.courses.index.courseCode()[$data] -->
<tr data-bind="css: { mutated: $root.mutated.indexOf($data.courseCode()) > -1 }">
<td><span data-bind="text: $data.id"></span></td>
<td><span data-bind="text: $data.courseCode"></span></td>
<td><span data-bind="text: $data.courseTitle"></span></td>
<td><span data-bind="text: $data.coursecampus"></span></td>
</tr>
<!-- /ko -->
</tbody>
</table>
Here are my two issues
- When I filter the search, my mutable array becomes empty, therefore all the element become expanded.
- I would love to convert my gpCourseCode to be a class similar to course, but I am not to sure how to do a distinct on a class and not just one element.
I have a jsfiddle here
解决方案
When I filter the search, my mutable array becomes empty, therefore all the element become expanded.
That's because you have an error in your click handler. It should take a function reference and not a function call. So click: $root.switchMutated($data)
should become: click: $root.switchMutated
(within a foreach, the click handler gets passed the current item as its first parameter automatically).
You will however now have to initialize the mutated
array yourself (or maybe reverse the logic so you don't have to). Your click handler was doing this by accident, since supplying a function call to the click handler will cause that function to be executed.
推荐阅读
- c# - 将一个文本文件中的字符串行与另一个文本文件进行比较,并在发生不匹配时显示错误
- javascript - 如果一个函数不使用等待,它是否应该是异步的
- objective-c - 带有 NSFetchedResultsController 的 UICollectionViewController 坏了,当更新所有对象的属性时,如果控制器按此属性排序
- django - 如何将数据从 get_avatar()(Google 登录)发送到我的模板?
- python - 使用 python PIL 调整文件夹中的图像大小
- python - 编写返回列表中最短单词的函数
- sass - 为什么 `gulp-sass` 看不到我的 `mixins.scss` 文件?
- javascript - 未捕获的语法错误:意外的标记“?”
- python - spacy train 后的最终模型是否使用整个数据创建?
- python - Django:插入或更新数据库条目