我正在开发Backbone中的示例ToDo列表项目,我想了解框架如何更喜欢在嵌套列表场景中组织其视图和模型。
为了澄清我的意思,我的单页Backbone应用程序应该显示ToDo列表的列表。从后端的角度来看,有一个List资源和一个Item(todo列表中的单个条目)资源。有点像:
由于我是一个Rails 3.2应用程序,我隐约地遵循Railscasts Backbone.js教程,所以这就是我从中获取当前设计的地方。我很想知道我是否完全脱离了Backbone规定的模式,或者我是否在正确的轨道上!
我到目前为止:
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
流程将是:
我基本上采用了List的设计,并将其镜像到一个级别。不同之处在于我不再需要依赖路由器。因此,我使用ListView的initialize方法产生类似的效果。
是的/不?超级错了?谢谢!
答案 0 :(得分:3)
TL:DR; 1)我会引导你的初始数据而不是fetch()reset()。 2)您可以根据需要在View的初始化中进行提取。或者您可以在开始时加载数据。请记住,如果您在init中获取,则异步性质将不会在渲染时准备好数据。如果你有一个等待同步/添加/等的监听器,这不是问题。 3)我不知道你对itemIndex对象的意思,但是你可以根据需要创建对象并添加它们。或者你可以在开始时加入,如果你知道你的所有列表最终将有一个集合。您可以根据需要重置(除非您给它选项{add:true},否则自动执行此操作)或者只是在它们进入时逐个添加它们虽然reset(),删除先前的视图,渲染所有视图似乎是人们通过完全获取()来做事的常用方法。
我认为它看起来很不错。关于Backbone的好处是你可以用很多不同的方式做到这一点。例如,您的数字2表示从视图中连接第二个fetch()。如果你想延迟加载,你可以这样做。或者你可以在任何事情完成之前抓住应用程序启动时的所有数据。这完全取决于你。我就是这样做的。
这就是我如何制作这样的应用程序(只是我的偏好,我不知道它更好或更差,或者它与你描述的相同。)
首先,我将创建一个名为ListModel的模型。它会有一个id和一个名字attr。这样,您就可以创建许多单独的列表,每个列表都有自己可以单独获取的ID。
每个ListModel都有一个ItemsCollection。这个集合有一个基于ListModel的URL,它是它的一部分。因此,ListModel-1的集合URL类似于/ list / 1
最后你有ItemModel,它是一个资源ID和文本。
ListCollection
ListModel // Monday Chores
ItemCollection
ItemModel // Mail
ItemModel // Laundry
ItemModel // Drycleaning
ListModel // Grocery
ItemCollection
ItemModel // Celery
ItemModel // Beef
所以在这个小小的展示中,你会注意到我还没有把任何与视图有关的东西。我不知道它是否更像是一个概念性的东西,但这就是数据层次结构的样子,你的观点可以完全独立于它。我不确定你是如何将上述观点纳入其中的,但我认为这可能会让它更清晰。
至于定义这些结构,我认为有两件事。
首先,我要确保我的ListModel已在我的集合中定义。这样我就可以使用集合add(hash)在我生成/添加它们时实例化新模型。
其次,我将定义ListModel,以便在创建一个ListModel时,它会自动创建一个ItemCollection作为该ListModel对象的属性(而不是属性)。
理想情况下,您的ListModel将是这样的:
ListModel.ItemCollection
在应用初始化之前,我会引导数据而不是fetch()。 (这种地址指出你所做的一点)理想情况下,当你的Backbone应用程序启动时,它应该具有从get go开始所需的所有必要数据。我会传递一些像这样的数据:
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。这取决于您的偏好和目标。你可能不需要这一切,但我觉得由于某种原因说明了。我不知道,也许有帮助。