2012-08-22 30 views
2

我正在研究Backbone中的示例ToDo列表項目,我想了解框架如何更喜歡我在嵌套列表場景中組織其視圖和模型。如何在示例Backbone.js待辦事項列表應用程序中構造兩個嵌套列表?

爲了闡明我的意思,我的單頁Backbone應用程序應顯示ToDo列表的列表。從後端的角度來看,有一個List資源和一個Item(一個待辦事項列表中的單個條目)資源。沿着線的東西:

  • 週一瑣事
    • 拿起郵件
    • 洗衣服
    • 拿起乾洗
  • 購物清單
    • 策lery
    • 牛肉
    • 你的想法...

由於礦井是Rails 3.2的應用程序,我隱約繼Railscasts Backbone.js的教程,所以這就是我從當前設計中獲得。我很想知道我是否瘋狂地脫離骨幹規定的模式,或者如果我走在正確的軌道上!

我迄今有:

ListsIndex View       //index of all lists 
\-- ListsCollection 
    \-- ListView/Model    //individual list 
      \-- ItemsIndex View   //index of items in one list 
       \-- ItemsCollection 
        \-- Item View/Model //individual todo item 

流程將是:

  1. 在路由器初始化,取上/列表後端路線列表()集合。在ListsIndex集合部分的'reset'事件上,對集合中的每個項目執行render(),並附加到列表索引視圖模板。
  2. 在每個項目視圖的初始化方法(這是你在哪裏連線第二級提取?)從/ lists /:id/items後端路由獲取()項目到ItemsCollection特定於那種觀點。
  3. 在相同的方法中,實例化ItemsIndex對象並將集合傳遞給它。再次,在ItemsIndex中,爲集合的填充時間設置一個「重置」事件處理程序,此時應該從項目集合中呈現每個提取的模型,並將它們附加到它自己的視圖中。

我基本上採取了列表的設計,並將其鏡像到其項目的一個級別。不同之處在於我不再需要依賴路由器。因此我使用ListView的初始化方法來達到類似的效果。

Yay/nay?超級錯了?謝謝!

回答

3

TL:DR; 1)我會引導你的初始數據而不是fetch()reset()。 2)你可以在你需要的時候初始化視圖。或者你可以在開始時加載數據。請記住,如果您在init中獲取數據,那麼異步本質將不會在渲染時準備好數據。如果你有一個監聽器在等待那個同步/添加/等等,這不是一個問題。3)我不知道你是什麼意思的itemIndex對象,但你可以創建對象,並添加到他們的集合,因爲你需要他們。或者,如果你知道所有的清單最終都會有一個集合,那麼你可以在開始時進行烘焙。你可以重置,如果你想(自動獲取,除非你給它選項{add:true}),或者只是在它們進來時逐個添加它們,儘管reset(),刪除先前的視圖,渲染所有視圖似乎是人們用完整的抓取()完成事情的常見方式。

我覺得它看起來不錯。 Backbone的好處是你可以用很多不同的方式做到這一點。例如,您的號碼2表示要從視圖中連線第二個提取()。如果你想延遲加載,你可以這樣做。或者您可以在任何事情完成之前在應用程序啓動時抓取所有數據。這真的取決於你。這是我可以做到的。

這是我怎麼可能做出這樣的一個應用程序(只是我的偏好,我不知道這是因爲你描述的任何好還是壞,或者如果它是相同的。)

首先,我將創建一個模型稱爲ListModel。它會有一個id和一個名字attr。這樣,您可以創建許多單獨的列表,每個列表都有自己的ID,可以單獨獲取。

每個ListModel的有它內部的ItemsCollection。這個集合有一個基於ListModel的URL,它是它的一部分。因此,對於ListModel的-1集URL會像/表/ 1

最後你ItemModel這是一個資源ID和文本。

ListCollection 
    ListModel // Monday Chores 
     ItemCollection 
      ItemModel // Mail 
      ItemModel // Laundry 
      ItemModel // Drycleaning 
    ListModel // Grocery 
     ItemCollection 
      ItemModel // Celery 
      ItemModel // Beef 

所以在這個小小的顯示中,你會注意到我沒有在視圖中做任何事情。我不知道它是否更像是一個概念性的東西,但這是數據層次結構的樣子,您的觀點可以是,應該完全獨立於它。我不確定你是如何包括上面的觀點的,但我認爲這可能會使它更清晰。

至於定義這些結構,我想兩件事。

首先,我要確保我的ListModel是我收集的定義。這樣我可以使用集合添加(哈希)來實例化新模型,因爲我產生/添加它們。

其次,我會定義的ListModel以便創建時一個,它自動創建一個ItemCollection作爲ListModel的物體(未作爲屬性)的屬性。

因此理想情況下,你的ListModels會是這樣:應用程序初始化

ListModel.ItemCollection 

之前,我會引導中的數據,而不是取()。 (這種類型的地址指向你創建的)理想情況下,當你的Backbone應用程序啓動時,它應該擁有它所需的所有必要數據。我會通過這樣的頭像這樣的一些數據:

var lists = [listModel-1-hash, listModel-2-hash]; 

現在,當應用程序啓動,你可以立即創建這兩個列表。

var myLists = new ListCollection(); 

_.each(lists, function(hash) { 
    myLists.add(hash); // Assumes you have defined your model in the ListCollection 
} 

現在您的列表集合具有它所需的所有列表模型。

這裏是哪裏的意見進來,你可以在任何傳遞給任何觀點。但我可能會將意見分解爲三件事情。

APPVIEW,ListModelView,ItemModelView,就是這樣。

想象的結構是這樣的:

<body> // AppView 
    <ul class="List"> // ListModelView 
     <li class="Item"></li>  // ItemModelView 
    </ul> 
    <ul class="List"> // ListModelView 
    </ul> 
</body> 

當你開始你的應用程序並創建一個APPVIEW,裏面APPVIEW你會生成每個ListModelView並將其追加到身體。我們的清單是空的。也許當你點擊它時,懶加載項目。這是你如何掛鉤它。

// In ListModelView 
events: {'click':'fetchItems'} 

fetchItems: function() { 
    this.model.itemCollection.fetch(); // Assumes you passed in the ListModel into view 
} 

因此,由於我引導數據開始,此fetch()調用將是您的「第二次」獲取。 (我正在處理您創建的第2點。)您可以在初始化中獲取它。請記住,它是一個異步函數,所以如果您在渲染時需要它們,它將無法工作。但是,您可以做的是將事件偵聽器添加到此視圖中,該偵聽器正在偵聽爲您的itemCollections添加事件。

this.model.itemCollection.on('add', this.addItemView, this); 

addItemView()將生成itemViews的新實例並追加它們。至於第3點,你可以在那個地方實例化一個集合,然後把它放到你的ListModel中。或者你可以做我所做的事情,並確保你的所有模型總是有一個ItemCollection。這取決於你的喜好和目標。你可能並不需要所有這些,但我想出於某種原因解釋它。我不知道,也許它有幫助。

+0

感謝您對推理的詳盡解釋!我會盡量把頭繞在身上,回到你身邊! –

+1

我喜歡從視圖中分離集合/模型的方法,以及在應用程序加載時預先加載數據的方法。我已經實現了懶加載的方法,但是我覺得它有點混亂。我提出的另一個發現是,正如你所建議的那樣,Backbone.js是完全沒有選擇的,因此可以讓你擺脫任何你喜歡的組織方式。這是很多繩子掛在一起,所以它必須非常審慎地使用。 –

相關問題