0
votes

I'm trying to render a partial view within a Backbone View with it's render method. I created a sort of helper to do this.

var DashboardPartial = (function(){

    var _getPartialView = function() {

        $.ajax({
          url: _baseUrl + _url,
        })

        .done(function(response) {
          _returnView(response);
        })
        .fail(function() {
          console.log("error");
        })
        .always(function() {
          console.log("complete");
        });

    };

    var _returnView = function (response) {
       return response;
    };

    return  {
      get: function (url) {
        _url = url;
        _baseUrl = '/dashboard/';
        _getPartialView();
      },

    };

}());

So, what I want to do is call DashboardPartial.get('url') and use the response within the Backbones View render method. Something like the following:

render: function() {
    partial = DashboardPartial.get('url');
    this.$el.html(partial); 
    return this;
}

The problem is that the function does get the partial from the server, but I can't find a way to return the response. Doing console.log(response) inside the DashboardPartial function does show the partial, but I want to be able to return it and then pass it as a variable to "this.$el.html()".

1

1 Answers

0
votes

You should return deferred ($.ajax returns it by default) from helper:

var DashboardPartial = (function(){

    var _getPartialView = function() {
        return $.ajax({
          url: _baseUrl + _url,
        });
    };

    return  {
       get: function (url) {
         _url = url;
         _baseUrl = '/dashboard/';
         return _getPartialView();
       },
    };
}());

And then use it in your render:

render: function() {
    var self = this,
        dfd = $.Deferred();

    DashboardPartial.get('url').done(function(partial){
        self.$el.html(partial);
        dfd.resolve();
    });

    return dfd; // use this outside, to know when view is rendered; view.render().done(function() { /* do stuff with rendered view */});
}

However, you could use requirejs for this, plus requirejs-text plugin to load templates, because your view has dependency on partial.

As I understood, you want render different partials using one backbone view.

You could create factory, smth like this:

var typeToTemplateMap = {};

typeToTemplateMap["backboneViewWithFirstPartial"] = firstPartial;

function(type) {
   return typeToTemplateMap[type];
}

And then use it in your view:

initialize: function(options) {
    this.partial = partialFactory(options.type);
},

render: function() {
    this.$el.html(this.partial);
    return this;
}

This is how it would look like using requirejs:

// factory.js

define(function(require) {

    var partialOne = require("text!path/to/partialOne.htm"), // it's just html files
        partialTwo = require("text!path/to/partialTwo.htm");

   var typeToPartialMap = {};

   typeToPartialMap["viewWithFirstPartial"] = partialOne;
   typeToPartialMap["viewWithSecondartial"] = partialTwo;

   return function(type) {
       return typeToPartialMap[type];
   }
});

// view.js

define(function(require){

   var Backbone = require("backbone"), // this paths are configured via requirejs.config file.
       partialFactory = require("path/to/factory");

   return Backbone.View.extend({

       initialize: function(options) {
           this.partial = partialFactory(options.type);
       },

       render: function() {
            this.$el.html(this.partial);
            return this;
       }
   });

});

// Another_module.js, could be another backbone view.
define(function(require) {
   var MyView = require("path/to/MyView"),
       $ = require("jquery");

   var myView = new MyView({type: "firstPartial"});

   myView.render(); // or render to body $("body").append(myView.render().$el);
});

You should consider using requirejs, because you doing almost the same, but without dependencies handling.

Docs on requirejs can be found here: http://requirejs.org/docs/start.html