Backbone-rails直接通过URL访问时不加载帖子

时间:2012-10-21 02:00:20

标签: ruby-on-rails backbone.js

所以我是Backbone的新手,我开发了一个带有JSON API的Rails应用程序,我已经将Backbone连接到了。

当我直接使用网站并按照链接时,每件事情都很有效。

在我点击指向/#/ 1的链接时,它会将我引导至显示页面,其中帖子的ID为1。

但是,如果我刷新页面,它将不再显示该信息,并抛出错误:

  

“未捕获的TypeError:无法调用未定义的方法'toJSON'”

当我进入控制台并访问我的观看BackboneBlog.router.show(1)时,它确实可以正常工作。只有当我去http://localhost:3000/#/1时我才会遇到问题。但是,当我点击索引页面中的链接时,会直接链接到http://localhost:3000/#/1

更加热闹的是BackboneBlog.router.posts是正确的。但是,如果在我的代码中我完全键入,但添加BackboneBlog.router.posts.get(1),则返回undefined。但是,如果我使用相同的URL在控制台中运行该确切的代码,它就可以工作。

这是我的代码:

  

posts_router.js.coffee -

class BackboneBlog.Routers.PostsRouter extends Backbone.Router
  initialize: ->
    @posts = new BackboneBlog.Collections.PostsCollection()
    @posts.fetch()

  routes:
    "": "index"
    "new"      : "newPost"
    "index"    : "index"
    ":id/edit" : "edit"
    ":id"      : "show"
    ".*"       : "index"

  newPost: ->
    @view = new BackboneBlog.Views.Posts.NewView(collection: @posts)
    $("#posts").html(@view.render().el)

  index: ->
    @view = new BackboneBlog.Views.Posts.IndexView(posts: @posts)
    $("#posts").html("")
    $("#posts").html(@view.render().el)

  show: (id) ->
    console.log(@posts) #puts PostsCollection, with posts in it
    console.log(id) #puts 1
    @post = @posts.get(id)
    console.log(@post) #puts undefined 
    @view = new BackboneBlog.Views.Posts.ShowView(model: @post)
    $("#posts").html(@view.render().el)

  edit: (id) ->
    post = @posts.get(id)

    @view = new BackboneBlog.Views.Posts.EditView(model: post)
    $("#posts").html(@view.render().el)
  

show_view.js.coffee -

BackboneBlog.Views.Posts ||= {}

class BackboneBlog.Views.Posts.ShowView extends Backbone.View
  template: JST["backbone/templates/posts/show"]

  render: ->
    $(@el).html(@template(@model.toJSON() ))
    return this
  

index_view.coffee -

BackboneBlog.Views.Posts ||= {}

class BackboneBlog.Views.Posts.IndexView extends Backbone.View
  template: JST["backbone/templates/posts/index"]

  initialize: () ->
    @options.posts.bind('reset', @addAll)

  addAll: () =>
    $("tbody").html("")
    @options.posts.each(@addOne)

  addOne: (post) =>
    view = new BackboneBlog.Views.Posts.PostView({model : post})
    @$("table").append(view.render().el)

  render: =>
    $(@el).html(@template(posts: @options.posts.toJSON() ))
    @addAll()

    return this
  

backbone_blog.js.coffee -

window.BackboneBlog =
  Models: {}
  Collections: {}
  Routers: {}
  Views: {}
  init: ->
    @router = new BackboneBlog.Routers.PostsRouter()
    Backbone.history.start()

全部谢谢! < 3

编辑:
tl; dr:如果我直接访问http://localhost:3000/#/1我会收到错误,但是,如果我链接到那里,它的效果非常好。如果我在控制台中输入它,它可以正常工作。只有当我直接导航到它不起作用的URL时。即便如此,在show方法中,每一件事都有效,直到我直接获得帖子

1 个答案:

答案 0 :(得分:1)

您的问题是您正在传递尚未提取的模型。因此模型未定义,因此您无法在未定义的模型上调用.toJSON。异步函数是非常误导的,特别是在尝试console.log时发生了什么。因此,举个例子,你可以在console.log中找到一个未定义的模型。现在,当获取该模型时,您记录的未定义模型将替换为已获取的数据。因此,它看起来好像是按顺序发生的,但实际上是将未定义的模型传递到视图中。

这就是为什么当你导航你的节目视图时,一切正常。这是因为您的收藏已经被提取。从show视图刷新时,仍然需要获取该集合,但是您的show视图不会等待您的集合被提取。

我希望这是有道理的。但为了向您展示我的意思,只需在您的路由器上调用您的show方法,即获取您的集合的成功回调。

如果我能进一步帮助你,请告诉我。