2012-12-21 45 views
2

我應該如何在BackboneJS中處理路由?在添加視圖後,路由時,我應該觸發一個事件,還是直接渲染視圖?路由和事件 - backboneJS

這裏有兩種情況:

觸發事件:

routes: { 
    'orders/view/:orderId' : 'viewOrder' 
}, 
viewOrder: function (orderId) { 
    var viewOrderView = new ViewOrderView(); 
    vent.trigger('order:show', orderId); 
} 

在我看來,我有:

var ViewOrderView = Backbone.View.extend({ 
    el: "#page", 
    initialize: function() { 
     vent.on('order:show', this.show, this); 
    }, 
    show: function (id) { 
     this.id = id; 
     this.render(); 
    }, 
    render: function() { 
     var template = viewOrderTemplate({ id: this.id }); 
     this.$el.html(template); 
     return this; 
    } 
}); 

或者,我應該走這條路:

routes: { 
    'orders/view/:orderId' : 'viewOrder' 
}, 
viewOrder: function (orderId) { 
    var viewOrderView = new ViewOrderView({id : orderId }); 
    viewOrderView.render(); 
} 

在我看來,我哈哈五個:

var ViewOrderView = Backbone.View.extend({ 
    el: "#page", 
    initialize: function() { 
     //init code here 
    }, 
    render: function() { 
     var template = viewOrderTemplate({ id : this.id}); 
     this.$el.html(template); 
     return this; 
    } 
}); 

認爲這是第一種情景 - 考慮到骨幹網是事件驅動的,但第二個明顯具有更少的代碼。

另外,我想第三個場景是保持視圖代碼在第一個場景,但抓住第二個路由器場景...呈現導航視圖,但暴露事件,以防我想觸發在其他地方。

想法?

回答

5

所以所有的骨幹問題通常都會以許多可能的答案結束。在這種情況下,我相信你的第二個例子是更典型/典型的骨幹模式。暫且不論處理負荷紡紗和數據加載後更新了棘手的問題,在你的路由器簡化的基本模式是:

routes: { 
    'orders/view/:orderId' : 'viewOrder' 
}, 

viewOrder: function (orderId) { 
    //Use models to represent your data 
    var orderModel = new Order({id: orderId}); 
    //models know how to fetch data for themselves given an ID 
    orderModel.fetch(); 
    //Views should take model instances, not scalar model IDs 
    var orderView = new OrderView({model: orderModel}); 
    orderView.render(); 
    //Exactly how you display the view in the DOM is up to you 
    //document.body might be $('#main-container') or whatever 
    $(document.body).html(orderView.el); 
} 

我認爲這是教科書模式。再次,觸發數據獲取並在到達後重新渲染的問題很棘手。我認爲最好的做法是如果視圖知道如何在模型獲取數據之前呈現自己的「加載」版本,然後當模型在獲取完成後觸發更改事件時,視圖會使用加載的模型數據重新渲染自己。但是,有些人可能會將這種邏輯放在別處。 This article on building the next soundcloud我想代表許多非常好的「最先進的」骨幹模式,包括他們如何處理未提取的模型。

通常,您可以根據自己的喜好使用回調或事件進行編碼。然而,一個很好的經驗法則是問自己一些問題:

  1. 是否有多個獨立的邏輯工作去響應這個事件?
  2. 我是否需要將此事件的來源與響應它的事情分開?

如果這兩個都是「是」,那麼事件應該是一個很好的選擇。如果兩者都是「否」,那麼比簡單的函數邏輯更適合。在「導航到此URL觸發此視圖」的情況下,通常這兩個問題的答案都是「否」,因此您可以將該邏輯編碼到路由器的路由處理程序方法中並使用該方法完成。

+1

我認爲還有一件事要考慮的是「誰應該知道誰」。即路由器應該知道視圖,還是應該瞭解路由器(或者兩者都不知道)?在這種情況下,我會和路由器一起了解視圖,而不是相反,因爲路由器就像是一個「全局」對象「,視圖應該只與視圖相關的視圖和模型(也可能是子視圖)在場景(1)中,視圖必須知道由路由器觸發的事件,這是沒有意義的。在場景2中,路由器知道視圖,但視圖不知道路由器是否正確 – hajpoj

+0

休息一年,沒有時間消費/測試和標記爲答案) –

3

我會使用第二種方案。沒有看到使用第一種方法的好處。這將使更多的SENCE這種方式(但仍值得商榷):

/* ... */ 
routes: { 
    'orders/view/:orderId' : 'viewOrder' 
}, 
viewOrder: function (orderId) { 
    vent.trigger('order:show', orderId); 
} 
/* ... */ 
vent.on('order:show', function(orderId) { 
    var viewOrderView = new ViewOrderView(); 
    viewOrderView.render(); 
}); 

var ViewOrderView = Backbone.View.extend({ 
    el: "#page", 
    initialize: function (options) { 
     this.orderId = options.orderId; 
    }, 

    render: function() { 
     var template = viewOrderTemplate({ 
      id: this.orderId 
     }); 
     this.$el.html(template); 
     return this; 
    } 
}); 

這樣至少你可以觸發路由操作,而無需更新的URL。但使用Backbone.router.viewOrder(1)可能會達到同樣的效果。事件非常強大,但如果我真的不需要,我不會使用它們。

+0

我認爲你們的全球事件與我們已經擁有的路由器事件完全相同,增加了複雜性而沒有任何好處。 –

+0

我同意你的說法。在我看來,這個代碼只是比Scott描述的第一種方法更有價值(特別是如果他在取回成功回調中沒有事件觸發)。我一般會使用他的第二個場景。 –

+0

(fyi前往休息一年,沒有時間消費/測試並標記爲答案) –