多个模型子类的 Backbone.js 集合 [英] A Backbone.js Collection of multiple Model subclasses
问题描述
我有一个返回日志"列表的 REST Json API.有许多类型的日志可以实现不同但相似的行为.在数据库层的服务器端实现是一种单表继承,因此日志的每个 JSON 表示都包含其类型":
<预><代码>[{"type": "ULM", "name": "My uml logbook", ... , specific_uml_logbook_attr: ...},{"type": "Plane", "name": "我的飞机日志", ... , specific_plane_logbook_attr: ...}]我想在客户端复制这个服务器模型,所以我有一个基本的 Logbook
类和多个 logbook 子类:
class Logbook 扩展了 Backbone.Model类 UmlLogbook 扩展日志类飞机日志扩展日志...
我的 Backbone.Collection
是我用来查询 JSON API 的一组 Logbook
模型:
class LogbookCollection 扩展 Backbone.Collection型号: 日志网址:/api/日志"
当我获取 logbook 集合时,有没有办法将每个 Logbook
转换为其相应的子类(基于 JSONtype"属性)?
确实有.
当您对集合调用fetch"时,它会在将响应添加到集合之前通过 Backbone.Collection.parse 传递响应.
'parse' 的默认实现只是按原样传递响应,但您可以覆盖它以返回要添加到集合中的模型列表:
class Logbooks 扩展了 Backbone.Collection型号: 日志网址:'api/日志'解析: (resp, xhr) ->_(resp).map (attrs) ->切换属性类型当 'UML' 然后是新的 UmlLogbook attrs当 'Plane' 然后新的 PLaneLogbook attrs
哇,idbentley 在我之前到达那里.唯一的区别是他使用每个"而我使用地图".两者都可以,但不同.
使用each"有效地打破了fetch"调用开始的链(通过返回undefined"——因此对reset"(或add")的后续调用将什么都不做)并在那里完成所有处理在解析函数中.
使用map"只是将属性列表转换为模型列表,并将其传递回已经在运动中的链.
不同的笔画.
再次刚刚意识到还有另一种方法可以做到这一点:
集合上的 'model' 属性仅存在于集合中,如果它在 'add'、'create' 或 'reset' 中传递属性,则该集合知道如何创建新模型.所以你可以这样做:
class Logbooks 扩展了 Backbone.Collection模型:(属性,选项)->切换属性类型当 'UML' 然后是新的 UmlLogbook attrs, options当 'Plane' 然后新的 PLaneLogbook attrs, options# 应该在这里添加一个'else',这样就有一个默认值,如果,# 比如说,没有为 Logbooks.create 调用提供属性网址:'api/日志'
这样做的好处是,集合现在将知道如何为获取"以外的操作转换"Logbook 的正确子类.
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) ?
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:
class Logbooks extends Backbone.Collection
model: Logbook
url: 'api/logbooks'
parse: (resp, xhr) ->
_(resp).map (attrs) ->
switch attrs.type
when 'UML' then new UmlLogbook attrs
when 'Plane' then new PLaneLogbook attrs
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:
class Logbooks extends Backbone.Collection
model: (attrs, options) ->
switch attrs.type
when 'UML' then new UmlLogbook attrs, options
when 'Plane' then new PLaneLogbook attrs, options
# should probably add an 'else' here so there's a default if,
# say, no attrs are provided to a Logbooks.create call
url: 'api/logbooks'
The advantage of this is that the collection will now know how to 'cast' the right subclass of Logbook for operations other than 'fetch'.
这篇关于多个模型子类的 Backbone.js 集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!