采用以下代码:
var model = new Backbone.Model({
items: new Backbone.Collection([
new Backbone.Model({ ID: 1 }),
new Backbone.Model({ ID: 2 })
])
});
var vm = new kb.ViewModel(model)
根据 KnockBack API 的说法(即: http://kmalakoff.github.io/knockback/tutorial_kb_view_model.html ),我预计“vm.items”将是一个 kb.CollectionObservable。
但是,当我尝试使用 kb.CollectionObservable 函数“filter”和“comparator”将排序和过滤函数归因于集合时,这些函数未定义。
vm.items.filters
= undefined
通常这些函数可以通过 viewModel 构造函数选项来指定,但在我的例子中,这些项目将作为更大的关系模型的一部分被拉下来(并且子 viewModel 目前正在使用工厂创建),所以我不能这样做就这样。
我已经确认从头开始创建一个新的 kb.collectionObservable 会揭示这些功能,即:
var collection = new kb.collectionObservable(new Backbone.Collection([
new Backbone.Model({ ID: 1 }),
new Backbone.Model({ ID: 2 })
]))
collection.filters
= function()
任何帮助将不胜感激。
最佳答案
所以最终的结果是,尝试将所有内容都变成 kb.collectionObservable 是错误的方法。更好的解决方案是创建一个辅助 ko.compulated 结果,然后实现我需要的所有过滤和排序。
var model = new Backbone.Model({
items: new Backbone.Collection([
new Backbone.Model({ ID: 1 }),
new Backbone.Model({ ID: 2 })
])
});
var vm = new kb.ViewModel(model);
vm.Sort() = ko.observable("asc");
vm.SortBy() = ko.observable("ID");
vm.Page() = ko.observable(1);
vm.Filters() = ko.observableArray([]);
vm.PageSize() = ko.observable(20);
vm.Filtered = ko.computed(function () {
var items = vm.items;
// Sorting
items = items.sort(function (first, second) {
var sortby = vm.SortBy();
if (first[sortby]() == second[sortby]()) return 0;
if (vm.Sort() == "asc") {
return first[sortby]() < second[sortby]() ? -1 : 1;
}
if (vm.Sort() == "desc") {
return first[sortby]() > second[sortby]() ? -1 : 1;
}
return 0;
});
// Filter
items = ko.utils.arrayFilter(items, function (vm) {
var filter = true;
$.each(vm.Filters(), function (i, filtr) {
var json = JSON.stringify(vm.model().attributes).toLowerCase();
if (json.indexOf(filtr.toLowerCase()) < 0) filter = false;
});
return filter;
});
// Paging
var startIndex = (vm.Page() - 1) * vm.PageSize();
var endIndex = vm.Page() * vm.PageSize();
items = items.slice(startIndex, endIndex);
return items;
});
此外,您可能还需要对模型本身设置排序,以便以正确的顺序添加新项目:
var setModelComparator = function () {
vm.model().get("items").comparator = function (a, b) {
var by = vm.Sort() == "asc" ? 1 : -1;
var field = vm.SortBy();
if (a.get(field) == 0) return -1 * by;
if (b.get(field) == 0) return 1 * by;
if (a.get(field) < b.get(field)) return 1 * by;
if (a.get(field) > b.get(field)) return -1 * by;
return 0;
};
};
也许这只是 Knockback 正在进行中的情况,并且没有更新 API 文档,谁知道呢。
也感谢 bvoleti 指出 Nested Models 的使用,击退武器库中非常重要的一部分,特别是与 Backbone.Relational 配合使用时.
关于javascript - Backbone.Collection 的 KnockBack ViewModel 似乎没有创建 kb.CollectionObservable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17194093/