문제

I've got a simple REST API that gives me data about an item at /api/items/:id, including ID and name. I'm using a Router to organise my Backbone views. The edit route instantiates a FormEditItem view, passing it the ID from the URL.

To get the data for the model from the API, the form view instantiates a new model, sets the ID and then calls the model's fetch method. (The second approach recommended in this thread.)

The model declaration is extremely simple:

App.Models.Item = Backbone.Model.extend({

    urlRoot: 'api/items'

});

And this is my form view:

App.Views.FormEditItem = Backbone.View.extend({

    template: _.template($('#tpl-formEditItem').html()),

    initialize: function(opts) {
        _.bindAll(this, "render");
        this.modelID = opts.modelID;
        this.parent = opts.parent;
        this.model = new App.Models.Item({id: this.modelID});
        this.model.fetch();
        this.render();
    },

    render: function() {
        console.log('Starting render:', this.model);
        console.log(this.model.get('name'));
        this.parent.$el.append(this.template(this.model.toJSON()));
        return this;
    }

});

In my form view's render function I'm logging out the model. I can see the model's attributes. But on the next line, when I try to log out the results of get('name'), I get undefined!

enter image description here

What's going on? Do I need to define a model's attributes before I try to fetch them from the database?

=============================================================================

EDIT

Following Stephen and Rida's advice, the fix in this situation is to add an event listener to the model's change event. The fetch operation takes some time to get the data from the API: I was trying to output the data before it arrived. So my initialize function should read:

    initialize: function(opts) {
        _.bindAll(this, "render");
        this.modelID = opts.modelID;
        this.parent = opts.parent;
        this.model = new App.Models.Item({id: this.modelID});
        this.listenTo(this.model, 'change', this.render);
        this.model.fetch();
    }

Thanks a lot guys!

도움이 되었습니까?

해결책

The problem is that you're trying to render the view before the fetch completes. In initialize, you call

this.model.fetch()

and then immediately call

this.render()

At that point the fetch won't have completed, so there won't be a name attribute.

When you look at the model in the console, that's after the fetch has completed, so then there is a name

다른 팁

Instead of these lines :

this.model.fetch();
this.render();

try to do

this.listenTo(this.model, 'change', this.render);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top