2014-07-21 15 views
0

我建立使用骨幹和coffeScript一個網站,當我從一個部分(innerpage)改變到另一個我替代的佈局爲一個新的渲染視圖和調用close方法舊的。一切似乎都很好,除了在主視圖上再次呈現小部件外,我還需要撥打twttr.widgets.load(),並且它每次都會創建一個新小部件,但似乎舊的部件會被保留,如果我移除它並不重要視圖或iframe節點,或者使容器元素爲空。我已經嘗試在移除視圖之前分離小部件,將其存儲在變量中,並在重新調用主視圖時使用它來放置小部件,而無需調用load方法,但iframe元素是唯一的被保存在變量中(儘管在刪除視圖之前它已經包含了所有內容),但我試過克隆節點,使用iframe內容,到目前爲止一切都失敗了。我似乎無法找到一種方法來卸載twttr obj中的twitter小部件,所以我最終會遇到一個令人討厭的內存泄漏,每次加載主視圖時總共會增加3mb,所以這不是一個選項,特別是對於手機,我最終可以將100MB分配給鬼部件。Twitter的部件泄漏內存

root = window ? global 

root.Backbone.View::close =()-> 
    @remove() 


class Otalvaro.Views.BaseContent extends Backbone.View 

    initialize: -> 
    @model.bind('sync', @render, this) 

這裏是我的家景(在這個版本中我試圖保存的iframe內容,普通版本,不檢查inMemory關閉與@Remove(視圖),並直接把內嵌框架)

編輯注意:刪除視圖不能在這裏工作,因爲在每個新的實例,小部件將創建一個新的iframe(小部件id甚至增加),所以我試圖保持只有homeview內存,因爲內存中有1個iframe比30個內部框架更好。

class Otalvaro.Views.Home extends Otalvaro.Views.BaseContent 
    template: root.template('homeTemplate') 

    initialize: -> 
    super 
    @inMemory = no 

    closeTwitterWidget: -> 
    $('iframe').unbind().remove() 

    close: => 
    @$el = @$el.clone() 
    @el = @$el[0] 
    @iframe = @$el.find('iframe').contents() 
    @inMemory = yes 

    render: (callback)-> 
    if(@inMemory) 
     console.log '@iframe', @iframe 
    else 
     console.log 'not in memory, doing normal rendering' 
     if _.isEmpty(@model.toJSON()) 
     console.log 'model is empty, fetching it now' 
     @model.fetch() 
     else 
     console.log 'model fetched, now rendering' 
     @$el.html(@template(@model.toJSON())) 
     # With out the delay, the widget won't load everytime 
     _.delay(-> 
      console.log 'firing twttr.widgets.load()' 
      root.twttr.widgets.load() # <- Guilty of all charges 
     , 630) 
     if callback? then callback(@el) 

    this 

這是layoutView的代碼的一部分,至極呈現在路線改變的看法:

class Otalvaro.Views.MainLayOut extends Backbone.View 
    el: '#mainContent' 

    closeOldViews: -> 
    if @oldViews? 
     for view in @oldViews 
     console.log 'view to be closed', view 
     view.close() 

    ### 
    # Takes an array containing one or more view instance as argument, adds a fadeOut fx to hide the current content 
    # then it renders each view instance from the array and extracts its node element (el) and pushes it into an array 
    # that is later (after the fadeIn completes) added as the html content of the layoutView 
    ### 
    show: (views)-> 
    @fadeOut() 
    delay = 500 
    viewNodes = [] 

    for view in views 
     node = view.render().el 
     viewNodes.push(node) 

    _.delay(
     _.bind -> 
     @closeOldViews() 
     @$el.html(viewNodes) 
     @fadeIn() 
     @oldViews = views 
    , this 
delay) 

路由器處理器產品,使用已實例化視圖,(也試過instanciating主視圖在路線的變化,但並沒有幫助)

home:-> 
    @mainLayout.show([@homeView]) 
    null 

編輯:添加 - >首頁模板

<script id="homeTemplate" type="text/x-handlebars-template"> 
    <blockquote id="homeQuote"> 
     <p>Some Quote</p> 
     <footer>Catalina Otalvaro</footer> 
    </blockquote> 
    <div class="twitterFeed fadeIn"> 
     <a href="https://twitter.com/kataotalvaro" data-widget-id="481647155510140928" class="twitter-timeline">Tweets by @kataotalvaro</a> 
    </div> 
</script> 

我讀過這對夫妻在tiwtter開發商論壇主題,但他們沒有得到答覆,我不是很有經驗這一點,所以如果有人outthere對我應該如何解決這個問題,我有什麼建議真的很感謝,感謝你的時間閱讀我的問題:)

https://dev.twitter.com/discussions/30128 https://dev.twitter.com/discussions/5957

回答

0

我設法解決了這個問題,通過在我的視圖的屬性中存儲小部件(<div>在小部件iframe中)來獲取小部件並不像存儲文檔中的任何節點那樣直截了當,必須在iframe容器(主容器)爲空或者iframe也將爲空之前進行存儲。現在,這條道路上的主要問題是將widget重新安裝到視圖中,但是我發現將html內容添加到當前不在DOM上的iframe中是不可能的(或者它似乎是這樣),因爲那是我的因爲iframe實際上只是在視圖的模板中,所以我決定將小部件附加到div,然後我需要的只是採用iframe樣式並將其添加到我的主樣式中(有一些修改),現在當我重申我的家庭觀點是從記憶中獲取靈感,並且沒有內存泄漏,在導航時我獲得了6mb左右的頂部,並且從未上升,使用widget.load()它高達50mbs。我不認爲這是理想的解決方案,它實際上是一種黑客攻擊,Twitter應該提供一種卸載小部件的方式,而不僅僅是加載方法。如果有人在同一地點,我希望這會有所幫助。抽出寶貴的時間來回答=)

感謝@glortho下面是修改主頁視圖

class Otalvaro.Views.Home extends Otalvaro.Views.BaseContent 
    template: root.template('homeTemplate') 

    initialize: -> 
    super 
    @inMemory = no 
    @memoryRender = no 

    close: => 
    unless @inMemory 
     @$iframe = $($('.twitter-timeline').contents().find('body').html()) 
     @inMemory = yes 

    render: (callback)-> 
    unless @memoryRender 
     if(@inMemory) 
     @$el.find('.twitterFeed').html(@$iframe) 
     @memoryRender = yes 
     else 
     console.log 'not in memory, doing normal rendering' 
     if _.isEmpty(@model.toJSON()) 
      console.log 'model is empty, fetching it now' 
      @model.fetch() 
     else 
      console.log 'model fetched, now rendering' 
      @$el.html(@template(@model.toJSON())) 
      _.delay(-> 
       console.log 'firing twttr.widgets.load()' 
       root.twttr.widgets.load() 
      , 630) 
      if callback? then callback(@el) 

    this 
0

你在Otalvaro.Views.Homeclose方法重寫基close方法,這意味着你每次關閉主視圖,你實際上並沒有刪除查看並進一步,你克隆元素:

@$el = @$el.clone(); 

這可能是因爲closeTwitterWidget將與一些能夠幫助去除的iframe,但我沒有看到那個被呼叫。

嘗試將close方法在您的主頁視圖中更改爲@remove()並查看它是如何發生的。

此外,是否爲您的主頁視圖元素肯定加載的Twitter小部件?

+0

嚴,也許我錯了解釋,一開始我用的是@Remove()並調用控件。再次load(),但它沒有工作,所以我重寫了close方法而不是實際關閉視圖,將其保存在內存中以再次追加它,但是當我reatach @ $ el時,它顯示除了內容之外的所有內容iframe中。是的,如果不是在內存中調用widget.load() – Zagen

+0

我看到'root.twttr.widgets.load()'被調用,但是什麼告訴這個小部件附加到主視圖?它在'homeTemplate'中嗎? – glortho

+0

Nopes,它由Twitter小部件代碼處理。模板上有一個鏈接,當它調用widgets.load()它發現它並用iframe替換它時,我將編輯我的問題以添加模板。 – Zagen