0

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

一切似乎都是正确的,除了当我在 localhost:3000 运行我的 js 控制台时不断收到错误,我得到以下信息:

   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

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

应用程序/资产/javascripts/voice.js.coffee

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

应用程序/资产/javascripts/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 .

javascripts/路由器/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)

javascripts/views/posts/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>

javascripts/collections/posts.js.coffee

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

javascripts/models/post.js.coffee

class Voice.Models.Post extends Backbone.Model

配置/路由.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

app/views/main/index.html.erb

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

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

4

1 回答 1

0

PostsIndex这样做:

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

但是您正在像这样实例化它:

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

我认为您想将路由器传递@collectionPostsIndex

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

Backbone 会自动将该collection选项转换为@collectioninside PostsIndex

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

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

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

于 2012-11-23T23:11:13.097 回答