Backbone和Rails 3 Uncaught TypeError:无法调用未定义的方法'on'

时间:2012-11-23 22:41:44

标签: jquery ruby-on-rails-3 backbone.js coffeescript railscasts

我正在开发一个应用程序,我正在关注这个rails cast:
http://railscasts.com/episodes/323-backbone-on-rails-part-1

一切似乎都是正确的,除了我在localhost运行我的js控制台时仍然收到错误:3000我得到以下内容:

   Uncaught TypeError: Cannot call method 'on' of undefined     posts_index.js:16
   Voice.Views.PostsIndex.PostsIndex.initialize                 posts_index.js:16
   Backbone.View                                                backbone.js:1147
   PostsIndex                                                   posts_index.js:10 
   Voice.Routers.Posts.Posts.index                              posts_router.js:24
   (anonymous function)                                         backbone.js:900
   (anonymous function)                                         backbone.js:1081
   _.some._.any                                                 underscore.js:209
   _.extend.loadUrl                                             backbone.js:1079
   _.extend.start                                               backbone.js:1046
   window.Voice.initialize                                      voice.js:10
   (anonymous function)                                         voice.js:15
   fire                                                         jquery.js:975
   self.fireWith                                                jquery.js:1083
  jQuery.extend.ready                                           jquery.js:407
  DOMContentLoaded                                              jquery.js:84

这是我的集合,模型,视图,路由器和模板的主干代码:

应用程序/资产/ Javascript角/ voice.js.coffee

Window.Voice =
    Models: {}
    Collections: {}
    Views: {}
    Routers: {}
    initialize: ->
            new Voice.Routers.Posts()
            Backbone.history.start()
$(document).ready ->
    Voice.initialize()

应用程序/资产/ Javascript角/ application.js中

//= require jquery
//= require jquery_ujs
//= require underscore
//= require backbone
//= require voice
//= require_tree ../templates
//= require_tree ./models
//= require_tree ./collections
//= require_tree ./views
//= require_tree ./routers
//= require_tree .

Javascript角/路由器/ posts_router.js.coffee

class Voice.Routers.Posts extends Backbone.Router
    routes:
            '': 'index'
    initialize: ->
            @collection = new Voice.Collections.Posts()
            @collection.fetch()
    index: ->
            view = new Voice.Views.PostsIndex()
            $('#container').html(view.render().el)

Javascript角/视图/帖/ posts_index.js.coffee

class Voice.Views.PostsIndex extends Backbone.View

    template: JST['posts/index']

    initialize: ->
            @collection.on('reset', @render, this)

    render: ->
            $(@el).html(@template(posts: @collection))
            this

应用程序/资产/模板/帖/ index.jst.eco

<h1> BACKBONE WORKS</h1>
<tr><td>
<%= @posts %>
</td></tr>

Javascript角/集合/ posts.js.coffee

class Voice.Collections.Posts extends Backbone.Collection
    url: '/api/posts'
    model: Voice.Models.Post

Javascript角/模型/ post.js.coffee

class Voice.Models.Post extends Backbone.Model

配置/ routes.rb中

Voice::Application.routes.draw do
    match '/login' => 'session#create'
    get 'logout', to: 'session#destroy', as: 'logout'
    resources :users
    scope "api" do
            resources :posts
    end
root :to => "main#index"
end

控制器/ posts_controller.rb

class PostsController < ApplicationController
  def index
    render :json => Post.all
  end

  def show
    render :json => Post.find(params[:id])
  end

  def upvote
    @post = Post.find(params[:id])
    current_user.like(@post)
    render :json => @post
  end

  def downvote
    @post = Post.find(params[:id])
    current_user.dislike(@post)
    render :json => @post
  end

  def create
    @post = Post.create!(:content => params[:content])
    render :json => @post
  end
end

应用程序/视图/主/ index.html.erb

<table class = 'table table-bordered table-condensed table-hover'>
        <div id='container'>
        </div>
</table>

Backbone很难调试,我已经投入了12个小时+。有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

您的PostsIndex执行此操作:

initialize: ->
    @collection.on('reset', @render, this)

但你要像这样实例化它:

class Voice.Routers.Posts extends Backbone.Router
    #...
    index: ->
        view = new Voice.Views.PostsIndex()

我想你想把路由器的@collection传递给PostsIndex

view = new Voice.Views.PostsIndex(collection: @collection)

Backbone PostsIndex内的automatically convert that collection option to @collection

  

构造函数/初始化 new View([options])

     

[...]有几个特殊选项,如果通过,将直接附加到视图:modelcollectionelidclassNametagNameattributes

在构建collection: @collection时只包括PostsIndex就足够了。