2012-08-22 85 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是完全没有选择的,因此可以让你摆脱任何你喜欢的组织方式。这是很多绳子挂在一起,所以它必须非常审慎地使用。 –

相关问题