将Backbone.js异步获取操作绑定到视图的正确方法

时间:2013-12-04 03:37:04

标签: javascript backbone.js

我想知道是否有关于“获取”的最佳方式的指针,然后将数据集合绑定到Backbone.js中的视图。

我正在使用异步获取操作填充我的集合,并成功将结果绑定到要在页面上显示的模板。由于异步提取操作在主线程执行,我失去对骨干视图对象的引用(在本例中为SectionsView)。在这种情况下,我无法引用$ el来追加结果。我被迫在页面上创建另一个DOM引用来注入结果。这有效,但我对

这个事实感到不满意

执行异步获取时,我丢失了对视图的引用,是否有更简洁的实现方法?我觉得我错过了一些东西......任何指针都会受到赞赏。

SectionItem = Backbone.Model.extend({ Title: '' });
SectionList = Backbone.Collection.extend({
    model: SectionItem,
    url: 'http://xxx/api/Sections',
    parse: function (response) {
        _(response).each(function (dataItem) {
            var section = new SectionItem();
            section.set('Title', dataItem);
            this.push(section);
        }, this);

        return this.models;
    }
});

//Views---
var SectionsView = Backbone.View.extend(
        {
            tagName : 'ul',
            initialize: function () {
                _.bindAll(this, 'fetchSuccess');
            },
            template: _.template($('#sections-template').html()),
            render: function () {
                var sections = new SectionList();
                sections.fetch({ success: function () { this.SectionsView.prototype.fetchSuccess(sections); } }); //<----NOT SURE IF THIS IS THE BEST WAY OF CALLING fetchSuccess?
                return this;
            },
            fetchSuccess: function (sections) {
                console.log('sections ' + JSON.stringify(sections));
                var data = this.template({
                    sections: sections.toJSON()
                });
                console.log(this.$el); //<-- this returns undefined ???
                $('#section-links').append(data); //<--reference independent DOM div element to append results
            }
        }
    );

1 个答案:

答案 0 :(得分:1)

darthal,你为什么重新实现解析?它似乎完全按照Backbone默认执行的操作(从AJAX调用接收模型数组并创建模型+将它们添加到集合中)。

现在问你的问题......你应该使用Collection的 reset 事件进行渲染。添加或删除单个实例时,您还有添加删除,但是提取将重置集合(删除所有然后添加全部)并且只会触发一个事件,重置,删除/添加的次数不多。

所以在你的初始化中:

this.collection.on("reset", this.fetchSuccess, this);

如果你想知道this.collection的来源,你需要在创建它时给你的视图,你可以传递一个模型或一个集合,或两者兼而有之,它们将自动成为添加到对象(视图)的上下文中。该参数的值应该是SectionList的一个实例。

您还必须更新fetchSuccess以依赖this.collection而不是某些参数。如果您需要遍历所有模型以执行诸如将HTML附加到DOM之类的内容,则Backbone集合提供.each方法。

在大多数情况下,您不需要fetchSuccess,您应该只使用渲染:当集合准备就绪时(重置&#39;),根据集合渲染DOM。

总结一下最常见的模式:

  1. 集合应独立于视图:您将集合作为视图创建的参数提供,不应从特定视图创建集合。

  2. 将View绑定到集合的重置事件(+ add,如果需要,删除)以运行render()

    this.collection.on(&#34; reset&#34;,this.render,this);

  3. 您可以随时对集合进行抓取(可能是在您初始化应用时)。

  4. 启动应用程序的典型代码如下所示:

    var sections = new SectionList();
    var sectionsView = new SectionsView({collection: sections});
    sections.fetch();
    

    由于您在视图的初始化中绑定了重置事件,因此您不必担心任何事情,视图的渲染()将在获取后运行。