2012-05-24 57 views
70

我正在實現我的第一個實際的非教程骨幹應用程序,並且有關使用backbone.js的一個方面的2-ish問題沒有解決對我來說很好,它涉及將視圖的呈現el注入到DOM中,與使用現有元素el相關。我懷疑我會在這裏爲您提供一些「可教授的時刻」,並感謝您的幫助。將backbone.js視圖附加到現有元素與將el插入DOM

大多數骨幹查看示例我在Web中看到指定tagName,id和/或className時創建一個視圖,從而創建一個從DOM不附加的el。他們通常看起來像這樣:

App.MyView = Backbone.View.extend({ 
    tagName: 'li', 
    initialize: function() { 
    ... 
    }, 
    render: function() { 
     $(this.el).html(<render an html template>); 
     return this; 
    } 
}); 

但教程並不總是解釋他們如何建議獲取呈現EL到DOM。我已經看到了幾種不同的方式。所以,我的第一個問題是:在哪裏調用視圖的render方法並將其el插入到DOM中? (不一定是同一個地方)。我已經看到它在路由器中完成,在視圖的初始化或渲染函數中,或者僅在根級文檔就緒函數中完成。 ($(function())。我可以想象任何這些工作,但有沒有一個正確的方法來做到這一點?其次,我從一些HTML標記/線框開始,並將html部分轉換爲與骨幹視圖相對應的js模板。與其讓視圖呈現一個獨立的元素並在html中提供一個錨點來堅持它,我覺得它更自然,當只有一個元素用於視圖時,它不會消失,作爲el本身使用現有的空的包裝元素(通常是divspan)。這樣,我就不必擔心文件中找到的地方插入我的獨立的EL,這將有可能最終看起來像這樣(請注意多分層):

<div id="insert_the_el_in_here"> <!-- this is all that's in the original HTML doc --> 
    <div id="the_el"> <!-- i used to be a backbone generated, unattached el but have been rendered and inserted --> 
     <!-- we're finally getting to some useful stuff in here --> 
    </div> 
</div> 

因此,我的第二個問題的一部分對於一個基本靜態的視圖,從頁面的HTML中直接使用現有的元素有什麼不對,因爲我的視圖的el?這樣我就知道它已經在DOM中,在正確的位置,並且調用render將立即渲染頁面上的視圖。我會通過將已經exixting的元素作爲'el'傳遞給我的視圖的constsructor來實現這一點。這樣,在我看來,我不必擔心將它粘到DOM上(使問題1成爲模擬),並且調用render將立即更新DOM。例如。

<form> 
    <div someOtherStuff> 
    </div> 
    <span id="myView"> 
    </span> 
</form> 

<script type="text/template" id = "myViewContents"> . . . </script> 

<script type="application/javascript"> 
window.MyView = Backbone.View.extend({ 
    initialize: function() { 
      this.template = _.template($('#myViewContents').html()); 
      this.render(); 
    }, 
    render: function() { 
      $(this.el).html(this.template()); 
      return this; 
    } 
}); 
$(function() { 
    window.myView = new MyView({ el: $('#myView').get(0) }); 
}); 
</script> 

這是一個好方法來做它的頁面靜態視圖?即只有其中一種觀點,在任何情況下都不會消失。或者,還有更好的方法?我意識到,根據我如何使用視圖,可能有不同的方式來做事情(例如,在路由器中,在父視圖中,在頁面加載等),但現在我正在查看初始頁面加載用例。

感謝

回答

53

但絕對沒有錯,附加以現有的DOM節點的想法。

您甚至可以將el作爲屬性放在您的視圖上。

window.MyView = Backbone.View.extend({ 
    el: '#myView', 
    initialize: function() { 
      this.template = _.template($('#myViewContents').html()); 
      this.render(); 
    }, 
    render: function() { 
      this.$el.html(this.template()); // this.$el is a jQuery wrapped el var 
      return this; 
    } 
}); 
$(function() { 
    window.myView = new MyView(); 
}); 

我建議是,做什麼工作的...骨幹的妙處在於,它是靈活的,能夠滿足您的需求。

就常見模式而言,通常我發現自己有一個主視圖來跟蹤視圖,然後可能是列表視圖和單個項目視圖。

就初始化而言的另一種常用的模式是有某種應用程序對象的管理的東西...

var App = (function ($, Backbone, global) { 
    var init = function() { 
     global.myView = new myView(); 
    }; 

    return { 
     init: init 
    }; 
}(jQuery, Backbone, window)); 

$(function() { 
    App.init(); 
}); 

就像我之前說,雖然,沒什麼做事沒有錯誤的方式,只是做什麼工作。 :)

如果您需要任何幫助,請隨時在twitter @ jcreamer898上打我,也可以查看@derickbailey,他是一位BB大師。

玩得開心!

+1

另外,感謝您使用模塊模式的提示。我一直在用require.js作爲實現模塊和動態加載以及所有好東西的一種方式,但是我們使用了很多非AMD插件和現有的代碼,我覺得它可能更簡單,並且更容易忽略有意義的文件和模塊中的東西,在可能的情況下使用類似上面指出的模塊模式的東西,並將它們連接/縮小以用於生產。 –

+1

絕對的,require.js是一個很好的解決方案,但它肯定會很棘手。通常我只會使用像模塊模式這樣的模式,然後使用命名空間將事情保持在窗口外。很高興我能幫上忙! – jcreamer898

+0

感謝您指向正確的方向。還發現$(this.el)的工作方式與此不同。$ el –

18

您也可以將HTML DOM元素對象作爲選項的'el'屬性發送到視圖中。

window.MyView = Backbone.View.extend({ 
    initialize: function() { 
      this.template = _.template($('#myViewContents').html()); 
      this.render(); 
    }, 
    render: function() { 
      this.$el.html(this.template()); // this.$el is a jQuery wrapped el var 
      return this; 
    } 
}); 
$(function() { 
    window.myView = new MyView({ 
     el: document.getElementById('myView') 
    }); 
}); 
+4

準確的答案我正在尋找。謝謝! – zachwill