0

我的问题是关于使用主干显示记录列表的正确方法。假设您有一个要显示给用户的人员模型,并允许他们按名字、姓氏、id 排序......

第一个直觉是让视图捕捉事件并根据用户排序选项重新渲染。这种方法的问题在于它是 UI 驱动的,而不是数据驱动的。

第二个想法是在模型中设置排序属性,因为集合不包含属性(尽管这似乎是最好的选择)。这种方法至少是通过设置排序属性来驱动数据,但是非常冗余,如果在保存时没有剥离排序属性,它们将被发送到服务器 | 本地或...

最后一个想法可能是正确的。创建第二个模型,该模型将用作包含排序/显示属性的控制模型。我对这种方法的问题是事件和模型会变得非常不守规矩。如果你扩展的不仅仅是一个人模型,而是一个相当大的应用程序,你就会有很多模型和事件,并且很难管理。model-1 视图必须捕获初始事件,然后让集合触发自定义事件,然后第二个模型必须捕获自定义事件并呈现它。

很抱歉这篇长文,我对主干 js 还很陌生,想确保我掌握了最佳实践。在此先感谢您的帮助。我希望我至少在正确的轨道上。

4

1 回答 1

1

我昨晚刚刚实施了这个。

您可以设置一个新的集合comparator,然后sort在集合上使用该方法。sort将触发一个reset事件,您可以在视图中使用它来重新呈现列表。

这是我的视图,其中包含一个选择框,允许用户选择如何对数据进行排序:

App.HouseListView = Backbone.View.extend({
    el: '.house-list',
    initialize: function() {
        App.houseCollection.bind('reset', this.populateList, this);

    },
    events: {
        'change .sort':'sort',
    },
    populateList: function(collection) {
        this.$('ul').html('');
        _.each(collection.models, function(model) {
            var view = new App.HouseListElemView({model:model});
            this.$('ul').append(view.el);
        });
    }, 
    sort: function(e) {
        var sort_by = $(e.srcElement.selectedOptions[0]).attr('data-sort-by');
        App.houseCollection.comparator = function(house) {
            return house.get(sort_by);
        }
        App.houseCollection.sort();
    },
});

希望这可以帮助

编辑:已实施@mu is too short的建议:

App.Houses = Backbone.Collection.extend({
    model: App.House,
    url: API_URL,
    _sort_by: 'price',
    sort_houses_by: function(sort_by) {
        this._sort_by = sort_by;
        this.sort();
    },
    comparator: function(house) {
        return house.get(this._sort_by);
    },
});


App.houseCollection = new App.Houses();

App.HouseListView = Backbone.View.extend({
    el: '.house-list',
    initialize: function() {
        App.houseCollection.bind('reset', this.populateList, this);

    },
    events: {
        'change .sort':'sort',
    },
    populateList: function(collection) {
        this.$('ul').html('');
        _.each(collection.models, function(model) {
            var view = new App.HouseListElemView({model:model});
            this.$('ul').append(view.el);
        });
    }, 
    sort: function(e) {
        var sort_by = $(e.srcElement.selectedOptions[0]).data('sort-by');
        App.houseCollection.sort_houses_by(sort_by);
    },
});
于 2012-06-17T16:02:07.147 回答