【问题标题】:KnockBack ViewModel of Backbone.Collection doesn't seem to create kb.CollectionObservableBackbone.Collection 的 KnockBack ViewModel 似乎没有创建 kb.CollectionObservable
【发布时间】:2013-06-19 14:34:50
【问题描述】:

取以下代码:

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 函数“过滤器”和“比较器”将排序和过滤函数归于集合时,这些函数是未定义的。

vm.items.filters
= undefined

通常可以通过 viewModel 构造函数选项指定这些函数,但在我的情况下,这些项目将作为更大的关系模型的一部分被下拉(目前正在使用工厂创建子视图模型)所以我不能这样做就这样吧。

我已经确认从头开始创建一个新的 kb.collectionObservable 会显示这些功能,即:

var collection = new kb.collectionObservable(new Backbone.Collection([
    new Backbone.Model({ ID: 1 }),
    new Backbone.Model({ ID: 2 })        
]))

collection.filters
= function()

任何帮助将不胜感激。

【问题讨论】:

标签: javascript backbone.js viewmodel


【解决方案1】:

所以最终结果是试图将所有内容都变成 kb.collectionObservable 是错误的方法。更好的解决方案是创建一个辅助 ko.computed 结果,然后实现我需要的所有过滤和排序。

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 文档,谁知道呢。

还要感谢 bvoletti 指出了 Nested Models 的使用,这是击退武器库中非常重要的一部分,尤其是与 Backbone.Relational 合作时。

【讨论】:

    猜你喜欢
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2023-01-13
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多