Backbone 获取响应为空数组时,获取成功回调未执行

Backbone Fetch success callback not executing when fetch response is an empty array

我有 Person 模型,我正在视图中检索人物信息。 success 回调 FetchSuccess 在响应有对象时执行。但是当响应为空时,不会调用回调。猜猜看?

Models.Basic = Backbone.Model.extend({
    parse: function(response) {
        return response;
    }
});

Models.PersonModel = Backbone.Model.extend({
    url: function() {
        return '/person/' + this.data.id;
    }
});

Backbone.View.extend({

    template: Templates['template'],

    initialize: function(options) {
        this.id = options.id;
        _.bindAll(this, 'FetchSuccess');

        this.personModel = new Models.PersonModel();
        this.model = new Models.Basic();
        this.fetchData();
        return this;
    },

    render: function() {
        this.$el.append(this.template(this.model.toJSON()));
    },

    fetchData: function() {
        this.personModel.data = {
            id: this.id
        };
        this.personModel.fetch({
            context: this,
            success: this.FetchSuccess
        });
    },

    FetchSuccess: function() {
        this.model.set({
            name: this.personModel.get('name');
        });
        this.render();
    }
});
this.personModel = new Models.PersonModel();

这是一个Backbone模型,不是一个集合。

this.personModel.fetch({
    reset: true, // this doesn't exist on model
    success: this.FetchSuccess
});

您无法获取没有 id 的模型。此外,模型在获取时期望返回一个对象。

如果你想获取特定的人,给模型一个id,然后获取。

this.personModel = new Models.PersonModel({ id: "id_here" });
// ...
this.personModel.fetch({
    context: this,
    success: this.FetchSuccess
});

这是经过更正的代码

// parse isn't needed if you're not going to parse something
Models.Basic = Backbone.Model.extend({});

Models.PersonModel = Backbone.Model.extend({
    urlRoot: 'person/', // this handles putting the id automatically
});

Backbone.View.extend({
    template: Templates['template'],

    initialize: function(options) {
        this.id = options.id;

        // pass the id here
        this.personModel = new Models.PersonModel({ id: this.id });

        this.model = new Models.Basic();
        this.fetchData();

        // makes no sense in the initialize since it's never called 
        // manually and never used to chain calls.
        // return this; 
    },

    render: function() {
        // render should be idempotent, so emptying before appending
        // is a good pattern.
        this.$el.html(this.template(this.model.toJSON()));

        return this; // this is where chaining could happen
    },

    fetchData: function() {
        // This makes no sense unless you've stripped the part that uses it.
        // this.personModel.data...

        this.personModel.fetch({
            context: this, // pass the context, avoid `_.bindAll`
            success: this.onFetchSuccess,
            error: this.onFetchError
        });
    },

    onFetchSuccess: function() {
        this.model.set({
            name: this.personModel.get('name')
        });
        this.render();
    },
    onFetchError: function() { this.render(); }

});

您可以使用 error 回调捕获错误,或者什么都不做并默认渲染,并在获取时重新渲染。

您还可以收听模型事件(在 initialize 内):

this.listenTo(this.personModel, {
    'sync': this.FetchSuccess,
    'error': this.onFetchError
});
this.personModel.fetch();