user2317084
user2317084

Reputation: 321

BackboneJS view keeps returning not defined

I can't seem to initialize my view. I tried looking around to see if this was asked before, but none of the solutions were working for me. My backbonejs view is below:

class FRView extends Backbone.View
  el: $ 'fr_view'

  initialize: ->
    console.log("created")

  render: ->
    console.log("here")

I'm attemtpting to intialize it inside of a partial using the code below:

:javascript
  var curr_view = new FRView()

but I keep getting the following error:

Uncaught ReferenceError: FRView is not defined

I've also tried

:javascript
  var curr_view = new Backbone.View.FRView()

Which lead to the following error:

Uncaught TypeError: Backbone.View.FRView is not a constructor

From chrome sources browser I can see that the FRView file is loaded. I've also tried wrapping it in document onload but that didn't help. Any idea what might be causing this issue?

Upvotes: 1

Views: 36

Answers (2)

user2317084
user2317084

Reputation: 321

As 'mu is too short' pointed out, the issue rooted from namespace/declaration issues. After googling around about namespace I skimmed through this and fixed the issue by changing my backbonejs view to:

class Portal.Views.FRView extends Backbone.View
    el: $ '#FRView'

    initialize: ->
        console.log("created")

    render: ->
        console.log("here")

and instantiated it using:

:javascript
    var frview = new Portal.Views.FRView();

Upvotes: 0

mu is too short
mu is too short

Reputation: 434615

I see two bugs, one you know about and one that you'll find out about soon.

The first problem (the one you know about) is caused by CoffeeScript's scoping system:

Lexical Scoping and Variable Safety
[...]
Although suppressed within this documentation for clarity, all CoffeeScript output is wrapped in an anonymous function: (function(){ ... })();

So your FRView ends up looking more or less like this in JavaScript:

(function() {
  var FRView = ...
})();

and that means that FRView is only visible inside your CoffeeScript file.

The easiest solution is to put the class in the global scope:

class @FRView extends Backbone.View

or equivalently:

class window.FRView extends Backbone.View

Another common solution is to define a global namespace for your app and then put your class in that namespace:

class YourNameSpace.FRView extends Backbone.View

and say new YourNameSpace.FRView when instantiating it.


The other problem is that your el looks a bit confused:

el: $ 'fr_view'

There are two problems here:

  1. That will be looking for an <fr_view> element in your HTML and you probably don't have such a thing. I'd guess that you really have something like <div id="fr_view"> or maybe <div class="fr_view">, in that case you'd want to say:

    el: '#fr_view' # If you're using an id attribute.
    el: '.fr_view' # If you're using a CSS class.
    
  2. $ 'fr_view' will be executed when the JavaScript is loaded and the element might not exist at that time. The solution to this problem is to use just the select for el as above. There's no need to use a jQuery object for el, Backbone will do that for you when the view is instantiated.

Upvotes: 2

Related Questions