2011-11-19 24 views
0

與backbone有幾天的問題,但無法找到解決方法或在stackoverflow上找到解決方案。Rails + Backbone.js:無法訪問視圖中的對象

我使用的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沒有定義,第三種情況正常工作。

第二件事是我無法訪問已經「硬編碼」到頁面中的任何DOM元素,並且不是由Javascript創建的。我知道這個原因,並且一直在Stackoverflow上閱讀關於它的帖子loooot,但我無法獲得任何解決方案。任何提示不勝感激。

最好的問候, 菲爾

編輯: 它似乎有事情做與頁面上的對象,類同頁的硬編碼的DOM元素的接入訪問的時機。如果我按照以下方式編輯我的視圖,即使能夠在代碼中的那一點之前,我也無法再訪問@ options.payment_methods。

EDIT2:加了我相應的路由器文件:(這簡直是骨幹護欄寶石例子的修改版本 「博客」)

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' 
+0

我可能是錯的,但你的問題的症狀似乎以配合那些看過來 - HTTP ://lostechies.com/derickbailey/2011/11/09/backbone-js-object-literals-views-events-jquery-and-el/ – vikmalhotra

+0

呵呵謝謝!我昨天偶然發現了這個帖子,因爲它確實符合我的症狀。仍然沒有成功! : -/ – user966041

回答

0

您確實需要查看並瞭解->=>之間的區別。它看起來像你班上的大多數方法使用->,當他們應該使用=>。無論您使用@something,它確實是this.something的快捷方式,而=>確保this確實是您期望的結果。使用->時,this將被綁定到進行調用的函數中,而不是您的類實例。

0

選項被傳遞給視圖的初始化方法。所以你可以直接訪問它們。

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

撥打render()@options應該沒事,只是在渲染不會被調用在您的視圖的情況下,即從其他一些回調的事件。爲了解決這個問題,用胖箭頭​​定義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(...) 

好運

+0

@maxlOrd非常感謝您的解釋。在「render:=>」如果我這樣做「alert @ options.payment_methods.get(1).get('payment_type')」它給我錯誤「this.options.payment_methods.get(1)未定義」,但仍然用正確的數據顯示警報。有什麼想法嗎? – user966041

+0

確保實例化Blog.Routers.PostsRou​​ter並啓動整個事件的代碼在文檔準備好後運行? – maxl0rd