Backbone.js 多个 Model 子类的集合
我有一个 REST Json API 返回列表“日志”。有许多类型的日志实现不同但相似的行为。在数据库层上的服务器端实现是一种单表继承,因此日志的每个 JSON 表示都包含其“类型”:
[
{"type": "ULM", "name": "My uml logbook", ... , specific_uml_logbook_attr: ...},
{"type": "Plane", "name": "My plane logbook", ... , specific_plane_logbook_attr: ...}
]
我想在客户端复制此服务器模型,因此我有一个基本 < code>Logbook 类和多个日志子类:
class Logbook extends Backbone.Model
class UmlLogbook extends Logbook
class PlaneLogbook extends Logbook
...
我的 Backbone.Collection
是一组 Logbook
模型,我用它来查询 JSON API:
class LogbookCollection extends Backbone.Collection
model: Logbook
url: "/api/logbooks"
当我获取时日志收集,有没有办法将每个 Logbook
转换为其相应的子类(基于 JSON“type”属性)?
I have a REST Json API that returns a list "logbooks". There are many types of logbooks that implement different but similar behavior. The server side implementation of this on the Database layer is a sort of Single Table Inheritance, so each JSON representation of a logbook contains its "type" :
[
{"type": "ULM", "name": "My uml logbook", ... , specific_uml_logbook_attr: ...},
{"type": "Plane", "name": "My plane logbook", ... , specific_plane_logbook_attr: ...}
]
I would like to replicate this server model on the client side, so I have a base Logbook
class and multiple logbook sub classes :
class Logbook extends Backbone.Model
class UmlLogbook extends Logbook
class PlaneLogbook extends Logbook
...
My Backbone.Collection
is a set of Logbook
models that i use to query the JSON API :
class LogbookCollection extends Backbone.Collection
model: Logbook
url: "/api/logbooks"
When I fetch the logbook collection, is there a way to cast each Logbook
to its corresponding sub class (based on the JSON "type" attribute) ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
确实有。
当您对集合调用“fetch”时,它会先通过 Backbone.Collection.parse 传递响应,然后再将其添加到集合中。
“parse”的默认实现只是按原样传递响应,但您可以覆盖它以返回要添加到集合中的模型列表:
编辑:哇,idbentley 在我之前到达那里。唯一的区别是他使用“每个”而我使用“地图”。两者都会起作用,但有所不同。
使用“each”有效地打破了“fetch”调用开始的链条(通过返回“undefined” - 因此随后对“reset”(或“add”)的调用将不执行任何操作),并在解析中进行所有处理功能。
使用“map”只是将属性列表转换为模型列表,并将其传递回已经运行的链。
不同的笔画。
再次编辑:刚刚意识到还有另一种方法可以做到这一点:
集合上的“模型”属性仅存在,以便集合知道如何在“添加”、“创建”或“重置”中传递属性时创建新模型。因此,您可以执行以下操作:
这样做的优点是,集合现在知道如何为“获取”以外的操作“转换” Logbook 的正确子类。
There is indeed.
When you call 'fetch' on a collection, it passes the response through Backbone.Collection.parse before adding it to the collection.
The default implementation of 'parse' just passes the response through, as is, but you can override it to return a list of models to be added to the collection:
EDIT: whoa, idbentley got there before me. the only difference being he used 'each' and I used 'map'. Both will work, but differently.
Using 'each' effectively breaks the chain that the 'fetch' call started (by returning 'undefined' - the subsequent call to 'reset' (or 'add') therefore will do nothing) and does all the processing right there in the parse function.
Using 'map' just transforms the list of attributes into a list of models and passes it back to the chain already in motion.
Different strokes.
EDIT AGAIN: just realized there's also another way to do this:
The 'model' attribute on a collection is there only so the collection knows how to make a new model if it's passed attributes in 'add', 'create' or 'reset'. So you could do something like:
The advantage of this is that the collection will now know how to 'cast' the right subclass of Logbook for operations other than 'fetch'.
是的。您可以覆盖集合上的
parse
函数(我将使用 javascript 而不是 Coffeescript,因为这是我所知道的,但映射应该很容易):希望这会有所帮助。
Yes. You can override the
parse
function on the collection (I'm gonna use javascript instead of coffeescript, because it's what I know, but the mapping should be easy):Hope this helps.
从主干 0.9.1 开始,我开始使用 esa-matti suuronen 的 pull-request 中描述的方法:
https://github.com/documentcloud/backbone/pull/1148
应用补丁后,您的集合将如下所示:
我相信这适合您,因为您正在使用 STI (所有型号都有唯一的 ID)
as of backbone 0.9.1, i've started using the method described in esa-matti suuronen's pull-request:
https://github.com/documentcloud/backbone/pull/1148
after applying the patch, your collection would be something like this:
i believe this would fit since you're using STI (all models have unique ids)
parse
可以单独工作,或者您可以使用 submodelTypes Backbone-Relational 的功能。parse
can work on its own, or you could use the submodelTypes feature of Backbone-Relational.也许使用 eval 不好,但这是更红宝石风格的方式(coffeescript):
所以你不需要编写很多 switch/cases,只需在 JSON 中设置 type 属性即可。它与rails+citier 或其他多表继承解决方案配合得很好。您可以添加新的后代,而无需将它们添加到您的案例中。
您可以在其他需要大量开关/外壳的地方使用此类结构,具体取决于您的模型类别。
Maybe it's bad to use eval, but this is much more ruby-style way (coffeescript):
So you don't need to write a lot of switch/cases, just set type attribute in your JSON. It works very good with rails+citier or other multitable inheritance solution. You can add new descendants without adding them to your cases.
And you can use such constructions in other places where you need a lot of switch/cases depending on your model class.