2011-08-18 100 views
17

從技術上可以嵌套的意見,嵌套視圖中使用的模板,這樣的事情:Backbone.js的:通過模板

<%= new PhotoCollectionView({model:new PhotoCollection(model.similarPhotos)}).render().el) %> 

我可以把所有的東西在渲染方法爲好,但模板給多少更多的靈活性和佈局空間。

我嘗試了上述變體,但是我在屏幕上得到的結果是[HTMLDivElement]

如果我試圖僅僅使用jQuery的HTML提取HTML,我得到它的呈現,但事實證明,打印出來的DOM節點與視圖持有的引用不同,因爲使用視圖實例不可能與這些DOM節點進行任何交互。例如,如果在視圖內我說$(this.el).hide(),什麼都不會發生。

什麼是正確的方法,如果有的話?

+1

我不確定這種技術在技術上是否可行,但是我會推薦它,因爲模板應該只包含簡單的條件語句而不包含任何應用程序邏輯。應用程序邏輯應該保留在你的視圖中。通過這種方式,您可以清楚地分辨問題,並且您的應用程序將更易於維護。 –

+0

你可以使用React.js嵌套視圖 –

回答

30

我通常首先渲染父視圖。然後,我使用this.$('selector')方法來查找可以用作子視圖的el的子元素。

這是一個完整的例子:

var ChildView = Backbone.View.extend({ 
    //.. 
}) 

var ParentView = Backbone.View.extend({ 
    template: _.template($('#parent-template').html()), 
    initialize: function() { 
    _.bindAll(this, 'render'); 
    } 
    render: function() { 
    var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView. 
    return this; 
    } 
}); 

var v = new ParentView(); 
v.render(); 
+0

好吧,是的......我最終做了同樣的 – user802232

+5

這似乎有點低效。每次渲染父項時,您都要重新初始化子視圖。 –

+4

同意亞歷山德羅。除了效率低下之外,每當父視圖呈現時,您也會在子視圖中鬆開動態狀態。查看[Backbone.Subviews](https://github.com/rotundasoftware/backbone.subviews)以準備使用極簡解決方案 –

1

我不知道模板本身,但我已經完成了表和列表之前。在外部模板,只是有存根:

<script type="text/template" id="table-template"> 
    <table> 
     <thead> 
      <th>Column 1</th> 
     </thead> 
     <tbody> 
     </tbody> 
    </table> 
</script> 

,併爲個別項目: <%=字段1%>

然後在您的渲染方法,只是使個別項目和追加他們到tbody元素...

-1

初始化一個新的對象每次渲染時間對我來說非常低效的決定。 特別是這樣的:

render: function() { 
    var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView. 
    return this; 
    } 

理想父的渲染應該像

render: function() { 
    this.$el.html(this.template()); 
    this.childView1.render(); 
    this.childView2.render(); 
} 

和初始化父母當孩子們創作應該只發生:

initialize: function() { 
     this.childView1 = new ChildView1(selector1); 
     this.childView2 = new ChildView2(selector2); 
} 

問題我們在渲染父模板之前沒有選擇器1和選擇器2。這是我現在卡在哪裏:)

+1

這似乎並沒有真正回答這個問題,雖然建議似乎是合理的。一定要真正回答*問題*! –

12

接受的答案有一個主要缺陷,這就是ChildView將在每次渲染時重新初始化的事實。這意味着你將失去狀態並且可能不得不在每個渲染上重新初始化複雜的視圖。

我寫了一篇關於這個博客在這裏:http://codehustler.org/blog/rendering-nested-views-backbone-js/

總之,雖然,我會建議使用這樣的事情:

var BaseView = Backbone.View.extend({ 

    // Other code here... 

    renderNested: function(view, selector) { 
     var $element = (selector instanceof $) ? selector : this.$el.find(selector); 
     view.setElement($element).render(); 
    } 
}); 

var CustomView = BaseView.extend({ 

    // Other code here... 

    render: function() { 
     this.$el.html(this.template()); 
     this.renderNested(this.nestedView, ".selector"); 
     return this; 
    } 
}); 

你不需要,如果你不延長骨幹視圖想要的,renderNested方法可以放在任何你喜歡的地方。

通過上面的代碼,您現在可以在初始化方法中初始化ChildView,然後在調用render()時簡單地渲染它。

2

查看Backbone.Subviews mixin。這是一個爲管理嵌套視圖而構建的極簡混合框架,並且不會在每次渲染父項時重新初始化子視圖。