BackboneJS视图保持返回未定义

时间:2016-06-06 04:03:53

标签: ruby-on-rails backbone.js coffeescript haml

我似乎无法初始化我的观点。我试着四处看看是否曾经问过这个问题,但是没有一个解决方案适合我。我的主干观点如下:

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

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

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

我正在尝试使用下面的代码将其初始化为部分内容:

:javascript
  var curr_view = new FRView()

但我一直收到以下错误:

Uncaught ReferenceError: FRView is not defined

我也试过

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

导致以下错误:

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

从chrome源浏览器我可以看到FRView文件已加载。我也尝试将它包装在文档onload中,但这没有帮助。知道可能导致这个问题的原因吗?

2 个答案:

答案 0 :(得分:2)

我看到两个错误,一个你知道的,一个你很快就会发现的错误。

第一个问题(您所知道的问题)是由CoffeeScript's scoping system引起的:

  

词汇范围和可变安全性
  [...]
  虽然为了清楚起见在本文档中进行了抑制,但所有CoffeeScript输出都包含在匿名函数中:(function(){ ... })();

因此,您的FRView最终会在JavaScript中看起来或多或少:

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

这意味着FRView仅在您的CoffeeScript文件中可见。

最简单的解决方案是将该类放在全局范围内:

class @FRView extends Backbone.View

或等效地:

class window.FRView extends Backbone.View

另一个常见的解决方案是为您的应用定义全局命名空间,然后将您的类放在该命名空间中:

class YourNameSpace.FRView extends Backbone.View

并在实例化时说new YourNameSpace.FRView

另一个问题是你的el看起来有点困惑:

el: $ 'fr_view'

这里有两个问题:

  1. 那将在你的HTML中寻找<fr_view>元素,你可能没有这样的东西。我猜你真的有类似<div id="fr_view"><div class="fr_view">的东西,在这种情况下你想说:

    el: '#fr_view' # If you're using an id attribute.
    el: '.fr_view' # If you're using a CSS class.
    
  2. 加载JavaScript时将执行
  3. $ 'fr_view',此时元素可能不存在。此问题的解决方案是仅使用上面的el选项。没有必要为el使用jQuery对象,Backbone将在实例化视图时为您执行此操作。

答案 1 :(得分:0)

由于'mu太短'指出,问题源于命名空间/声明问题。在谷歌搜索命名空间后,我浏览了this并通过将我的backbonejs视图更改为:

来解决问题。
class Portal.Views.FRView extends Backbone.View
    el: $ '#FRView'

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

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

并使用:

实例化它
:javascript
    var frview = new Portal.Views.FRView();