2013-08-16 32 views
0

我页指出,本质上是一样的购物车结账过程中,像这样的序列:如何正确使用骨干的意见和路由器

var ItemsCollection = Backbone.Collection.extend({ 
    model: ItemModel,  
    url "/items" 
}); 

var ItemsView = Backbone.View.extend({ 
    // Select item on click event here 
}); 

var ItemsApp = Backbone.View.extend({ 
    // Fetch collection of items and render each ItemsView 

}); 

当选择一个项目,我想本质上的变化状态来呈现该项目的卖家。该架构是这样的:

var SellersCollection = Backbone.Collection.extend({ 
    model: SellersModel,  
    url "/sellers" // The item ID is stored in a session NOT in the url (So permalinks work) 
}); 

var SellersView = Backbone.View.extend({ 
    // Select item on click event here 
}); 

var SellersApp = Backbone.View.extend({ 
    // Fetch collection of sellers and render each SellersView 

}); 

因此,考虑这两种状态,哪里是基于地方实例化一个卖家集合,取卖方和渲染视图?

我在考虑将SellersApp视图和ItemsApp视图基本结合为一个控制器,用于确定要渲染哪个子视图以及要获取哪个集合。如果我这样做,是否应该在主应用程序名称空间中实例化BOTH集合并在需要时获取集合,或者是否应仅在调用相应状态(url)时实例化每个集合。我认为后一种方法违反了德米特法。

我觉得我该怎么做。

// 1. Instantiate outside the view 
var MainApp = Backbone.View.extend({ 

    attributes: { 
     "page": "items" 
    }, 

    items: function(){ 
     // Fetch items collection and render view (listenTo used in initialize) 
    }, 

    sellers: function() { 
      // Fetch sellers 
    } 

}); 

Items = new ItemsCollection; 
Sellers = new SellersCollection; 

这是一个好方法吗?如果这是一个好方法,我应该在哪里告诉MainApp更改状态 - 也就是说,是否应该明确调用主应用程序的获取收集方法(即,ItemsView'click'中的
,显式声明ItemsApp.sellers),还是应该使用主应用程序视图上的侦听器,可自动侦听要选择的项目。

我基本上寻找替代使用router.navigate - 触发器和使用路由器实例化每个视图/集合,因为我听说这不是好的做法。

+0

我试图找到正确的解决方案,以避免使用路由器的内置触发器:真正的方法。一直未能找到一个好例子。 – kevin

+0

您是否想要将内联列表中的卖家展示为展开视图,或者在选择项目时更改整个页面? –

+0

我宁愿让它充当一个完全独立的状态/视图。所以它就像您点击卖家页面上的固定链接一样,其中销售者基于服务器端存储的会话项目。 – kevin

回答

1

不幸的是,在骨干(特别是骨干视图)中,没有一种真正的“正确”方式来做事情。没有参考约定。很多使用Backbone的人只使用模型/集合,根本不使用视图。

在我看来,我会废除一个集合的观点,除非它实际上在做一些重要的事情。使用层次结构应用程序> ModelCollection + ModelViewCollection。

所以你的情况:

ItemsApp (Backbone.View) 
--ItemCollection (Backbone.Collection) 
    --Item (Backbone.Model) 
    -- SellerCollection (Backbone.Collection) 
--ItemViewCollection (Array) 
    --ItemView (Backbone.View) 
    -- SellerViewCollection (Array) 

所以你ItemsApp将创建和销毁ItemViews作为ItemCollection变化(听事件)。

ItemView有责任知道用户何时根据事件选择它。然后它可以选择在其模型上填充SellerCollection。未选中时可以清除该集合。它还监听SellerCollection中的更改并为每个卖家添加和删除视图。

我不认为有任何内置的方法来存储Backbone.Views的列表,你可能只是想创建自己的数组。视情况而定,由你自己决定,因为模型本身不应该引用其视图。

值得让全局事件对象充当一种消息传递系统。 Backbone.View实现Backbone.Events,以便您可以全局声明您的应用程序对象,然后监听任何事件。当你需要的时候,你应该只使用它,否则你应该直接听事件而不是全局触发事件。例如,您的ItemView可能有一个“返回”按钮,它引发一个名为“返回”的事件,而您的AppView正在监听活动ItemView上的事件,并且当它想要返回时,AppView将进行必要的更改到DOM并取消选择该项目。

+0

这将如何与永久链接进行交互/工作?如果用户直接进入卖家页面并且该项目存储在服务器上的会话中?我会使用路由器来调用该集合吗?那么它可能会有不同的表现,因为在你描述的用例中,集合是从子视图中调用的,对吧? – kevin

+0

路由器引发诸如“route:detail”之类的事件或路由名称,并将参数传递给这些事件。所以你的主ItemsApp听路由器。例如。 'router.on(“route:detail”,this.RouteDetail,this);' –

+0

然后该函数将采用ID或任何物品模型,并将其设置为应该触发视图更改的选定项目。基本上你是从一个路由器事件INSTEAD触发它的一个项目引发一个点击事件。只要你处理同样的触发事件,你怎么触发它都不重要。 –