#c# #knockout.js #knockout-2.0
Вопрос:
Как я могу сгруппировать и отфильтровать таблицу с помощью knockout.js. Я также пытаюсь развернуть и свернуть строку, и это код, в котором я несколько преуспел).
Это моя функция разграничения, обратите внимание, что на данный момент она, похоже, работает только с одним элементом данных ( я бы хотел, чтобы в будущем она отличалась от свойства объекта.
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;
};
Это моя текущая объектная функция
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);
}
Вот моя модель просмотра
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)
)
});
});
}
Это мой 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>
Вот мои две проблемы
- Когда я фильтрую поиск, мой изменяемый массив становится пустым, поэтому все элементы расширяются.
- Я бы хотел преобразовать свой gpCourseCode в класс, аналогичный курсу, но я не уверен, как сделать различие в классе, а не только в одном элементе.
У меня здесь есть jsfiddle
Ответ №1:
Когда я фильтрую поиск, мой изменяемый массив становится пустым, поэтому все элементы расширяются.
Это потому, что у вас ошибка в обработчике щелчков. Он должен принимать ссылку на функцию, а не вызов функции. Таким click: $root.switchMutated($data)
образом, должно стать: click: $root.switchMutated
(в течение каждого шага обработчик щелчка автоматически передает текущий элемент в качестве своего первого параметра).
Однако теперь вам придется инициализировать mutated
массив самостоятельно (или, возможно, изменить логику, чтобы вам не пришлось этого делать). Ваш обработчик щелчка делал это случайно, так как предоставление вызова функции обработчику щелчка приведет к выполнению этой функции.