使用Backbone.js的范围错误?

时间:2012-02-18 02:13:49

标签: javascript backbone.js

我认为我的问题在某种程度上与范围有关,因为我是一个新手。我有一个很小的backbone.js示例,其中我要做的就是打印出从服务器获取的项目列表。

$(function(){
    // = Models =
    // Video
    window.Video = Backbone.Model.extend({
        defaults: function() {
            return {
                title: 'No title',
                description: 'No description'
            };
        },
        urlRoot: 'api/v1/video/'
    });

    // VideoList Collection
    // To be extended for Asset Manager and Search later...
    window.VideoList = Backbone.Collection.extend({
        model: Video,
        url: 'api/v1/video/'
    });

    // = Views =
    window.VideoListView = Backbone.View.extend({
        tagName: 'ul',

        render: function(eventName) {
            $(this.el).html("");
            _.each(this.model.models, function(video) {
                $(this.el).append(new VideoListRowView({model:video}).render().el);
                }, this);
            return this;
        }
    });

    // VideoRow
    window.VideoListRowView = Backbone.View.extend({
        tagName: "li",

        template: _.template("id: <%= id %>; title: <%= title %>"),

        className: "asset-video-row",

        render: function() {
            $(this.el).html(this.template(this.model.toJSON()));
            return this;
        }
    });

    // Router
    var AppRouter = Backbone.Router.extend({

        routes:{
            "":"assetManager"
        },

        assetManager:function() {
            this.assetList = new VideoList();
            this.assetListView = new VideoListView({model:this.assetList});
            this.assetList.fetch();
            $('#content').html(this.assetListView.render().el);
        }
    });

    var app = new AppRouter();
    Backbone.history.start();

    // The following works fine:
    window.mylist = new VideoList();
    window.mylistview =  new VideoListView({model:window.mylist});
});

如果我从控制台访问mylist.fetch(); mylist.toJSON(),则mylist填充正常。我可以告诉this.assetList.fetch()准确地从后端获取数据,但它似乎没有将对象添加到this.assetList

1 个答案:

答案 0 :(得分:1)

Backbone集合上的fetch method是异步的:

  

从服务器获取此集合的默认模型集,在集合到达时重置集合。 [...] Backhind.sync的代表,负责自定义持久性策略。

Backbone.sync说:

  

Backbone.sync 是每次尝试将模型读取或保存到服务器时Backbone调用的函数。默认情况下,它使用(jQuery/Zepto).ajax发出RESTful JSON请求。

因此fetch涉及(异步)AJAX调用,这意味着您在fetch从服务器检索数据之前尝试使用该集合。请注意,fetch支持successerror回调,因此您可以这样做:

var self = this;
this.assetList.fetch({
    success: function(collection, response) {
        $('#content').html(self.assetListView.render().el);
    }
});

或者您可以将回调绑定到集合的reset事件,因为fetch将重置集合。然后在触发集合的assetListView事件时呈现您的reset

此外,您的assetList是一个集合,所以您应该这样做:

this.assetListView = new VideoListView({collection: this.assetList});

window.VideoListView = Backbone.View.extend({
    tagName: 'ul',

    render: function(eventName) {
        $(this.el).html("");
        _.each(this.collection.models, function(video) {
            // ...