Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get model attributes within a view in Backbone.js?

I am trying to pass a model as parameter in a view. I am getting my object in the view, but no way to access its attributes... Here is the code :

From the router :

var Product = new ProductModel({id: id});
Product.fetch();
var product_view = new ProductView({el: $("#main-content"), model: Product});

From the model :

var ProductModel = Backbone.Model.extend({
urlRoot: 'http://192.168.1.200:8080/store/rest/product/'
});

From the view :

ProductView = Backbone.View.extend({
    initialize: function(){
        console.log(this.model);
        this.render();
    },
    render: function(){
        var options = {
            id: this.model.id,
            name: this.model.get('name'),
            publication_start_date: this.model.get('publication_start_date'),
            publication_end_date: this.model.get('publication_end_date'),
            description: this.model.get('description'),
            applis_more: this.model.get('applis_more')
        }
        var element = this.$el;
        var that = this;
        $.get('templates/product.html', function(data){
            var template = _.template(data, options);
            element.html(template);
        });
    }
});

Here is the result of the "console.log":

child {attributes: Object, _escapedAttributes: Object, cid: "c1", changed: Object, _silent: Object…}
Competences: child
Editor: child
Hobbies: child
Opinions: child
_changing: false
_escapedAttributes: Object
_pending: Object
_previousAttributes: Object
_silent: Object
attributes: Object
createdDate: null
deletedDate: null
descriptionId: 0
galleryImage: null
id: 13
image: null
manufacturerId: 0
name: "sdf"
owner: 0
status: 0
thumbnail: null
titleId: 0
type: 1
uid: "fdsf"
updatedDate: null
__proto__: Object
changed: Object
cid: "c1"
id: 13
__proto__: ctor

In my view, all my options are "undefined" (name, dates,...)

Any idea on what I am doing wrong ?

like image 726
VeZoul Avatar asked Jan 14 '23 18:01

VeZoul


2 Answers

After creating the initial model, you're immediately creating the view using

var product_view = new ProductView({..., model: Product});

In the initialize method of ProductView, you're calling this.render(), which in turn reads and renders values from the model - most of these values are undefined (because the server did not have sufficient time to send back the model's values).
Don't call this.render() directly, but bind an event, eg:

// in ProductView::initialize
this.model.on('sync', function() {
    this.render();
}, this);

You might also want to bind the change event, so that local (not synchronizsed yet) changes to the model are also reflected in the view. (An overview of Backbone events can be found here.)

like image 142
Rob W Avatar answered Jan 30 '23 02:01

Rob W


Because Product.fetch() happens asynchronously, you'll want to create the view once the data has been retrieved from the server:

var Product = new ProductModel({id: id});
var product_view;
Product.fetch().done(function() {
    product_view = new ProductView({el: $("#main-content"), model: Product});
});
like image 42
Lukas Avatar answered Jan 30 '23 03:01

Lukas