backbone marionette pass variable to view method

864 views Asked by At

I have simple situation and can't understand why variable that I pass to function always undefined.

var ProjectItemView = Backbone.Marionette.ItemView.extend({
        template: "#ProjectItemTemplate",

        initialize: function () {

            var id = this.model.get('project_id');

            $.getJSON('service/api.php/projects/' + id + '/progress').done(function (data) {

                 this.renderProgress('4'); //<== pass here
            });

        },

        renderProgress: function (why) {
            alert(why);  //<== undefined
        ...
        },
    ...
});

I expect that it equals '4'. In next step I want to pass "data" but now I realize that I can't pass anything.

3

There are 3 answers

0
Alin On BEST ANSWER

You loose the context in $.getJSON done callback. Try this:

var ProjectItemView = Backbone.Marionette.ItemView.extend({
        template: "#ProjectItemTemplate",

        initialize: function () {

            var id = this.model.get('project_id');
            var _this = this;

            $.getJSON('service/api.php/projects/' + id + '/progress').done(function (data) {

                _this.renderProgress('4'); //<== pass here
            });

        },

        renderProgress: function (why) {
            alert(why);  //<== undefined
        ...
        },
    ...
});
0
Sunil Ajagekar On

You don't have access to this inside " $.getJSON( " assign this to any variable and then call "renderProgress" method.

var currentObj = this;

 $.getJSON('service/api.php/projects/' + id + '/progress').done(function (data) {

                 currentObj .renderProgress('4'); //<== pass here
            });

because in your case this points to current object of that function and not to view object.

2
seebiscuit On

Since you're invoking renderProgress on the return of $.getJSON you can simply provide the function reference to the done()method of the returned jQuery Promise. Your code would look like this:

var ProjectItemView = Backbone.Marionette.ItemView.extend({
        template: "#ProjectItemTemplate",

        initialize: function () {

            var id = this.model.get('project_id');

            $.getJSON('service/api.php/projects/' + id + '/progress')
             .done(this.renderProgress);
        },

        renderProgress: function (data) {
            alert(data); 
        ...
        },
    ...
});

If you'll need the view context inside renderProgress (like, for example, to refer to a view property), then provide done() a version of renderProgress that's bound to the view context:

$.getJSON('service/api.php/projects/' + id + '/progress')
 .done(_.bind(this.renderProgress, this));

where _.bind is an UnderscoreJS function. Read more about it here.