Jason Swett
Jason Swett

Reputation: 45094

Backbone view won't load JST

I have an app that utilizes Backbone.js. Everything was working fine, but recently I added RequireJS to my project, and that of course made everything break, so I'm in the processes of defining my dependencies and making everything work again.

The error I'm getting is Uncaught ReferenceError: JST is not defined.

I have the following CoffeeScript view file. Note the JST line:

define ["app"], (App) ->
  Snip.Views.Appointments ||= {}

  class Snip.Views.Appointments.IndexView extends Backbone.View
    template: JST["backbone/templates/appointments/index"]

    initialize: () ->
      @options.appointments.bind('reset', @addAll)

    addAll: () =>
      @options.appointments.each(@addOne)

    addOne: (appointment) =>
      view = new Snip.Views.Appointments.AppointmentView({model : appointment})
      @$("ul").append(view.render().el)

My "app" dependency itself has Backbone and Underscore as dependencies, so I don't think the problem is that Backbone is not present:

define ["underscore", "backbone"], (_, Backbone) ->
  window.Snip =
    Models: {}
    Collections: {}
    Routers: {}
    Views: {}

When I load the page, I get Uncaught ReferenceError: JST is not defined.

What do I need to do to get my script to know about JST?

Edit: here are my paths and stuff

require
  paths:
    jquery: "jquery-1.7.2.min"
    underscore: "lodash.min"
    appointment: "backbone/models/appointment"
    appointmentIndexView: "backbone/views/appointments/index_view"
    appointmentsRouter: "backbone/routers/appointments_router"
    relational: "backbone-relational"
  shim:
    "underscore":
      exports: "_"
    "backbone":
      deps: ["underscore", "jquery"]
      exports: "Backbone"
    "relational":
      deps: ["backbone"]

requirejs ["appointmentsRouter"], (AppointmentsRouter) ->
  window.router = new Snip.Routers.AppointmentsRouter({appointments: []})
  Backbone.history.start()

Upvotes: 1

Views: 6157

Answers (5)

Denis
Denis

Reputation: 2469

Specify correct loading order

require.config

require.config({
    paths: {

        // specify templates
        templates: 'compiled-templates'
    }
})

// firstly load templates
require(['templates'], function() {

    // then load you app
    require(['core/Core']);
});

Upvotes: 0

boldfacedesignuk
boldfacedesignuk

Reputation: 1643

Whilst Jason Swett was using AMD/require.js, as the question title is not specific I thought I'd answer on behalf of CommonJS/Browserify users as I ended up here after googling for the same issue.

After moving my Backbone app to Browserify is was getting a "JST in undefined error". wawka's answer above helped me to get things sorted.

Before I had:

JST["path/to/template"]({...});

Now I have:

var template = require("path/to/template");
...
template({...})

Hope this is of help to others.

Upvotes: 0

wawka
wawka

Reputation: 5154

I had the similar problem. I got an error in my Backbone View:

Uncaught ReferenceError: JST is not defined.

Below what I've done to make it work:

  1. In my config/requirejs.yml I sat:

    modules:
        - name: "products/product_price_tmpl"
    
  2. My view definition:

    define ['jquery', 'underscore', 'backbone', 'products/product_price_tmpl'] , ($, _, Backbone) ->
    
    Backbone.View.extend
    
        template: JST['products/product_price_tmpl']
    
        tagName: 'li'
    
        render: ->
            @$el.html(@template(@model.attributes))
            @
    
  3. All my templates are in the assets/templates directory. If requirejs has a problem to find your template in this directory, you can move templates directory into assets/javascripts folder or add this line to config/application.rb file:

    config.assets.paths << "#{Rails.root}/app/assets/templates"  
    

Upvotes: 1

jakee
jakee

Reputation: 18566

there is no variable called JST available when the module in question is loaded.

You need to add the path to your JST -library to the paths-attribute in require.config.

Then most likely you'll need to add it to shim also and make it export JST.

In require.js your alarm bells should start ringing when you use some external resource inside a module that has not been

A. Imported in the define -section of that module

B. Imported via require inside that module

C. Mentioned in your require.config -function

UPDATE

You need to make a new module (like templates.js), that returns a variable (for example JST).

define([
  ...
], function( ... ) {
  
  var JST = {};

  JST['template/name'] = "<div class='my-template'><%= my-content %></div>";

  ...

  return JST;
}

Then in the module you want to use those templates in:

define([
  ...
  'path/to/your/JST/module',
  ...
], function(..., JST, ...) {

// Et voilà, now you can use the templates like they should be used

});

Upvotes: 1

bluecubetheshiny
bluecubetheshiny

Reputation: 1

I am using Backbone Boilerplate which compiles the templates into one file called templates.js. the JST is defined in templates.js. configure the paths with templates.js resolved the issue.

Upvotes: 0

Related Questions