【问题标题】:Rails + Backbone.js: Having trouble accessing objects in viewRails + Backbone.js:无法访问视图中的对象
【发布时间】:2011-11-19 09:23:07
【问题描述】:

几天来骨干遇到问题,无法找到解决方法或在 stackoverflow 上找到解决方案。

我使用 Rails 3.1 + 最新的主干(+ coffeescript):

这是我的一个观点作为例子(所有观点都存在同样的问题):

Blog.Views.Payment ||= {}

class Blog.Views.Payment.PaymentView extends Backbone.View
  className:  'payment_method'
  tagName:    'td'
  events:
    'click #renderPayment':  'renderPayment'

  initialize: ->
    # CAN'T access @options.payment_methods here 
    @options.payment_methods.bind(###stuff###)

  render: ->
    # CAN'T access @options.payment_methods here either...
    $(@el).html ("### something with #{@options.payment_methods or @options.payment_methods.model}")
    return @

  updateView: ()->
    # updating view stuff...

  renderPayment:  ->
    # ACCESSING @options.payment_methods fine here!!!
    if ($("#payment_details").length == 0)
      $(@el).append("<ul id='payment_details'>
                       <li id='payment_type'>#{@options.payment_methods.get(1).get('payment_type')}</li>
                     </ul>
                       ").effect("highlight", 700)

在我运行示例的前两种情况下,浏览器告诉我 @options.payment_methods 未定义,第三种情况正常。

第二件事是我无法访问任何已经“硬编码”到页面中并且不是由 Javascript 创建的 DOM 元素。我知道其中的原因,并且一直在 Stackoverflow 上阅读大量关于它的帖子,但我找不到任何解决方案。任何提示都非常感谢。

最好的问候, 菲尔

编辑: 似乎与页面上对象的访问时机有关,类似于对页面硬编码DOM元素的访问。如果我按如下方式编辑我的视图,我将无法再访问@options.payment_methods,即使我之前能够在代码中访问。

# changed "renderPayment" to "$(document).ready" or just "$" in coffeescript
$  ->
  # ACCESS NOT possible anymore
  if ($("#payment_details").length == 0)
    $(@el).append("<ul id='payment_details'>
                     <li id='payment_type'>#{@options.payment_methods.get(1).get('payment_type')}</li>
                   </ul>
                     ").effect("highlight", 700) 

EDIT2:添加了我相应的路由器文件:(这只是主干导轨 gem 示例“博客”的修改版本)

class Blog.Routers.PostsRouter extends Backbone.Router
  initialize: (options) ->
    @posts = new Blog.Collections.PostsCollection()
    @posts.reset options.posts

    # ... other collections

    # fetch payment_methods collection
    @payment_methods = new Blog.Collections.PaymentMethodsCollection()
    @payment_methods.reset options.payment_methods
    @payment_methods.fetch()

    @model = ({posts: @posts, mails: @mails, addresses: @addresses, purchases: @purchases, payment_methods: @payment_methods})

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


  # main view
  index:  ->

    # render Product Info View
    @view = new Blog.Views.Product.ProductView(purchases: @purchases)
    $("#product_1").html(@view.render().el)

    ##### view etc.

    # render Payment View
    @view5 = new Blog.Views.Payment.PaymentView(payment_methods: @payment_methods)
    $("#customer_1").append(@view5.render().el)

   ### other views...

还有我的付款模式:

class Blog.Models.PaymentMethod extends Backbone.Model
  paramRoot: 'payment_method'

  defaults:
    payment_type: null
    # ...

class Blog.Collections.PaymentMethodsCollection extends Backbone.Collection
  model: Blog.Models.PaymentMethod
  url: '/payment_methods'

【问题讨论】:

  • 我可能错了,但您的问题症状似乎与这里的症状相符 - lostechies.com/derickbailey/2011/11/09/…
  • 呵呵谢谢!我昨天偶然发现了那个帖子,因为它似乎真的符合我的症状。还是没有成功! :-/

标签: ruby-on-rails dom view backbone.js coffeescript


【解决方案1】:

您确实需要查找并了解-&gt;=&gt; 之间的区别。看起来你的类中的大多数方法都使用-&gt;,而它们应该使用=&gt;。无论您在何处使用@something,它实际上都是this.something 的快捷方式,=&gt; 确保this 确实是您所期望的。使用-&gt;this 将绑定到进行调用的函数中的任何内容,而不是您的类实例。

【讨论】:

    【解决方案2】:

    选项被传递给视图的初始化方法。所以你可以通过这种方式直接访问它们。

    initialize: (options) ->
      # Now you have options
      options.payment_methods.bind(###stuff###)
    

    render() 中调用@options 应该没问题,除非在您的视图上下文中未调用render,即来自其他回调。要解决此问题,请使用粗箭头定义 render,它将始终在视图的上下文中调用。

    render: =>
      $(@el).html( ...etc...)
    

    如果您想访问页面上已有的元素,那么您需要做一些事情。最重要的是,将el 中的DOM 元素传递给视图构造函数,您的视图将“接管”并拥有该元素。比如……

    view = new Blog.Views.Payment.PaymentView(
      el: $("#product_whatever").get(0)
    )
    

    然后在该视图中,您希望将 jQuery 找到的范围限定为视图的元素。例如:

    render: =>
      $(@el).find('div.somewhere_else').html("change this")
    

    coffeescript 中的主干快捷方式是

    @$('div.somewhere_else').html(...)
    

    祝你好运

    【讨论】:

    • @maxlOrd 非常感谢您的解释。在“渲染:=>”中,如果我执行“警报@options.payment_methods.get(1).get('payment_type')”,它会给我错误“this.options.payment_methods.get(1) is undefined”,但仍然显示带有正确数据的警报。有什么想法吗?
    • 确保实例化 Blog.Routers.PostsRou​​ter 并启动整个事情的代码在文档准备好后运行?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 2014-02-02
    相关资源
    最近更新 更多