Javascript 使用Backbone.js将远程集合呈现到页面上

Javascript 使用Backbone.js将远程集合呈现到页面上,javascript,ruby-on-rails,ruby,backbone.js,coffeescript,Javascript,Ruby On Rails,Ruby,Backbone.js,Coffeescript,我使用Backbone.js和RubyonRails来呈现一组帖子,但屏幕上没有呈现任何内容 应用程序文件 #= require_self #= require_tree ./templates #= require_tree ./models #= require_tree ./views #= require_tree ./routers window.IntroProject = Models: {} Collections: {} Routers: {} Views:

我使用Backbone.js和RubyonRails来呈现一组帖子,但屏幕上没有呈现任何内容

应用程序文件

#= require_self
#= require_tree ./templates
#= require_tree ./models
#= require_tree ./views
#= require_tree ./routers

window.IntroProject =
  Models: {}
  Collections: {}
  Routers: {}
  Views: {}

  init: ->
    window.router = new IntroProject.Routers.HomepageRouter({})
    Backbone.history.start()

$ ->
  IntroProject.init()
模型与集合

class IntroProject.Models.Post extends Backbone.Model
  paramRoot: 'post'

class IntroProject.Collections.PostsCollection extends Backbone.Collection
  model: IntroProject.Models.Post
  url: '/'
路由器

class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts = new IntroProject.Collections.PostsCollection()
    @posts.fetch()


  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
    @view.render()
class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts = new IntroProject.Collections.PostsCollection()
    @posts.fetch({ reset : true })

  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts ||= new IntroProject.Collections.PostsCollection()

  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
    @posts.fetch()
看法

模板

  <script type="text/template" id="home-post-template">
  <div class="row">
    <div class="small-12 columns">
      <h2 class="blog-post-title"><%= post.title %></h2>
      <small>
        <p class="blog-post-meta">Published on <%= post.created_at.strftime('%B %d, %Y') %>
          <% if (post.user.email) %>
          by <strong><%= post.user.email %></strong>
          <% end %>
        </p>
      </small>
      <hr>
      <div class="blog-post-body">
        <p><%= post.body.html_safe %></p>
      </div>
    </div>
  </div>
  </script>
 <script type="text/template" id="home-post-template">
  <div class="row">
    <div class="small-12 columns">
      <h2 class="blog-post-title"><%= post.title %></h2>
      <small>
        <p class="blog-post-meta">Published on <%= post.created_at %>
          <% if (post.user.email) %>
          by <strong><%= post.user.email %></strong>
          <% end %>
        </p>
      </small>
      <hr>
      <div class="blog-post-body">
        <p><%= post.body %></p>
      </div>
    </div>
  </div>
  </script>
所以他们把这些帖子都收藏起来了

当我做
@$el.append(@template())
时,它说
post
未定义,所以我做了
@$el.append(@template(post:@collection.models)
。但是post未定义

总的来说,我知道发生了什么,但它不起作用。我错过了一些重要的事情。以下是

更新:

建议对答案进行修改

路由器

class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts = new IntroProject.Collections.PostsCollection()
    @posts.fetch()


  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
    @view.render()
class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts = new IntroProject.Collections.PostsCollection()
    @posts.fetch({ reset : true })

  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts ||= new IntroProject.Collections.PostsCollection()

  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
    @posts.fetch()
看法

模板,我从
post.title


现在我正在通过控制台获取未捕获的引用错误:标题未定义。

您的集合是异步获取的,这意味着当您在视图上调用render时,数据还不存在。您可以在
控制台中看到。log(@collection)
:其
长度
为0

您的视图需要侦听其集合,并在(无论何时)从服务器更改/返回时重新呈现。您可以将此函数添加到视图类中(不太熟悉CoffeeScript,如JS所述):

但由于在获取调用返回时未显式触发重置事件,请将其更改为(在路由器的设置中):

另外,您的视图的
render
函数在我看来并不正确,我会这样写

render : function(){
  _.each(this.collection, function(model){
    var html = this.template( model.toJSON() );
    this.$el.append( html );
  }, this);
}
这也意味着您需要在模板中替换对
post
的引用:

  • 替换`
  • 使用

在一些帮助下,我自己找到了答案。下面是固定代码的样子。如果不做任何更改,请省略

路由器

class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts = new IntroProject.Collections.PostsCollection()
    @posts.fetch()


  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
    @view.render()
class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts = new IntroProject.Collections.PostsCollection()
    @posts.fetch({ reset : true })

  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
class IntroProject.Routers.HomepageRouter extends Backbone.Router

  initialize: (options) ->
    @posts ||= new IntroProject.Collections.PostsCollection()

  routes:
    '':'index'

  index: ->
    @view ||= new IntroProject.Views.Posts.IndexView(collection: @posts)
    @posts.fetch()
看法

模板

  <script type="text/template" id="home-post-template">
  <div class="row">
    <div class="small-12 columns">
      <h2 class="blog-post-title"><%= post.title %></h2>
      <small>
        <p class="blog-post-meta">Published on <%= post.created_at.strftime('%B %d, %Y') %>
          <% if (post.user.email) %>
          by <strong><%= post.user.email %></strong>
          <% end %>
        </p>
      </small>
      <hr>
      <div class="blog-post-body">
        <p><%= post.body.html_safe %></p>
      </div>
    </div>
  </div>
  </script>
 <script type="text/template" id="home-post-template">
  <div class="row">
    <div class="small-12 columns">
      <h2 class="blog-post-title"><%= post.title %></h2>
      <small>
        <p class="blog-post-meta">Published on <%= post.created_at %>
          <% if (post.user.email) %>
          by <strong><%= post.user.email %></strong>
          <% end %>
        </p>
      </small>
      <hr>
      <div class="blog-post-body">
        <p><%= post.body %></p>
      </div>
    </div>
  </div>
  </script>

发布于 通过


问题在于fetch和render调用。路由器初始化时,我正在提取集合。集合不会保留到视图中。在我对视图调用render时,没有任何可渲染的内容


在解决方案中,在视图初始化之后,我现在有了
fetch()
。视图初始化之后,视图将在
fetch()之后呈现
成功地保留了要调用的
重置
事件。我选择将
el
作为
body
放置,因为我有需要
el
成为
body
的事件。事件在
el
中查找何时触发。

可能是
@posts.fetch()
函数。尝试在该函数中实现
成功
回调。回调示例获取:抱歉,我刚刚注意到一个错误,它应该是
@collection.each(function(post){…});
,您需要在帖子上调用
.toJSON()
postHtml=@template(post.toJSON())
,请参见以下基本示例:我已实施了您的更改,但无法使其生效。我已更新了问题以反映更改。我已经做了一周了,因此任何帮助都将非常有用。