GrantU
GrantU

Reputation: 6555

Getting attributes from models and displaying it within templates - Backbone

Could someone check over the following code and tell me why I cannot output any attributes from my model to templates? My views and template render correctly the model does fetch data and this should work...

Template:

Name should show here --> {{thisItem}}

I get no error and text shows but no {{thisItem}}. From reading the docs this should work.

I don't think my model is being passed to the template or is there a [dot] needed i.e. {{model.name}}?

My View:

define([
    'jquery',
    'underscore',
    'backbone',
    'models/myModel',
    'collections/myModelCollection',
    'hbs!templates/testExampleTemplate.html',
], function ($, _, Backbone, myModel, myModelCollection, testExampleTemplate) {
    var thisView = Backbone.Marionette.ItemView.extend({
        initialize: function (options) {
            this.model.fetch();
        },
        model: new myModel(),
        template: testExampleTemplate,
    });
    return thisView;

});

console.log of model showing I do have data:

    attributes: Object
          thisItem: "Example Item"

Model:

define([
    'underscore',
    'backbone',
    'jquery'
], function (_, Backbone, jquery) {

    var myModel = Backbone.Model.extend({
        urlRoot: '/myModel'
    });

    return myModel;

});

Template, this is how my works:

HTML Base

Layout view gets loaded into this i.e.

function (Marionette, Handlebars, template, jquery, model) {
    var LayoutView = Backbone.Marionette.Layout.extend({
        template: template,
        regions: {
            holder1: "#holder1"
        }
    });
    return LayoutView;
});

<div id="holder1">I will be replaced</div>

Then the view in question gets loaded into holder1.

Upvotes: 2

Views: 1156

Answers (1)

earl3s
earl3s

Reputation: 2373

This is an asynchronous issue. You need to listen to your model's change event before you render.

Try adding

modelEvents: {
    'change': 'render'
}

To your View. This will make sure your model has loaded its data before the view renders so your data shows up in your model.

Btw, modelEvents is specific to Marionette and not native to Backbone. You can do this:

var self = this;
this.model.fetch({'success': function() {
    self.render();
});

In your initialize function if you want to rely on Backbone alone.

This works because your model doesn't load its data from the server immediately. It takes a moment, and your code keeps executing. So you are rendering before the data has loaded. By waiting until it's loaded you are ensuring the template will render with the data. You can remove your other render call from wherever that is, because the view is now rendering itself. Side note, this will allow it to rerender whenever the data changes automatically.

Upvotes: 5

Related Questions