Search code examples
javascriptbackbone.jsunderscore.jsunderscore.js-templating

can pass backbone collection to view error string is not a function


i am new to backbone trying to send a collection directly to a view template but i fail. Type Error saying that string is not a function. I know that i return correctly my collection maybe i am taking the wrong way to pass my collection into view. Anyway help will be appreciate.

here my view code

var EncoursView = Backbone.View.extend({
   el: "#contentEncours", //Container div
   template: "tpl/EncoursView.html",
   initialize: function () {
                  console.log('Encours View Initialized');
                  this.collection.fetch();
                  console.log(this.collection);
               },
   render: function () {
                  $(this.el).empty();
                   var that = this;
                  //Fetching the template contents
                  $.get(this.template({lists:this.collection}), function (template) {
                    that.$el.html(template); //adding the template content.
                  }, 'html');

                  return that;
           }
});

this is my view trying to iterate my collection

<script>
_.templateSettings = {
    evaluate: /\{\{(.+?)\}\}/g,
    interpolate: /\{\{=(.+?)\}\}/g,
    escape: /\{\{-(.+?)\}\}/g
};
    {{ _.each(items, function(item) { }}
        <ul>
            <li>Isin: {{= item.isinCode }}</li>
        </ul>
    {{ }); }}
</script>

inside my route i call this function i pass collection to my view and call render

remencour: function(){
   var collectionSupport = new SupportCollection();
   this.encoursView = new EncoursView({collection:collectionSupport});
   this.encoursView.render();
}

Solution

  • I'm guessing that this:

    $.get(this.template({lists:this.collection}), function (template) {
        that.$el.html(template); //adding the template content.
    }, 'html');
    

    is meant to retrieve the template source (tpl/EncoursView.html) from the server, fill it in, and then insert it into the view's el.

    There are a couple problems here.

    1. this.template is the 'tpl/EncoursView.html' string when you try to call it like a function.

    2. $.get expects a URL as its first parameter.

    3. Inside the $.get callback, template should be the template source (once you get that far of course).

    4. Your template:

      {{ _.each(items, function(item) { }}
          <ul>
              <li>Isin: {{= item.isinCode }}</li>
          </ul>
      {{ }); }}
      

      doesn't really match the data you're trying to feed it.

    You have all the right pieces they're just not in the right places.

    1 and 2 are easy, just give $.get the template URL as its first argument. 3 is also fairly easy to deal with: compile the template inside the callback. 4 isn't that difficult either, feed the template serialized data and make sure the name you pass to the template function matches what the template uses:

    $.get(this.template, function(template) {
        var tmpl = _.template(template);
        var html = tmpl({ items: that.collection.toJSON() });
        // ---------------^^^^^------------------^^^^^^^^
    }, 'html');
    

    and the template would look the same as it does now.

    The toJSON call gives you an array of objects, this helps you avoid accidentally changing anything inside a template. This is standard practice with Backbone.