我有一个REST Json API,它返回一个列表“ logbooks”。有许多实现不同但相似行为的日志。在数据库层的服务器端实现是一种单表继承,因此日志的每个JSON表示都包含其“类型”:
[ {"type": "ULM", "name": "My uml logbook", ... , specific_uml_logbook_attr: ...}, {"type": "Plane", "name": "My plane logbook", ... , specific_plane_logbook_attr: ...} ]
我想在客户端复制此服务器模型,所以我有一个基Logbook类和多个日志子类:
Logbook
class Logbook extends Backbone.Model class UmlLogbook extends Logbook class PlaneLogbook extends Logbook ...
我的Backbone.Collection是一组Logbook用于查询JSON API的模型:
Backbone.Collection
class LogbookCollection extends Backbone.Collection model: Logbook url: "/api/logbooks"
当我获取日志集合时,是否有一种方法可以将每个对象Logbook转换为其对应的子类(基于JSON“ type”属性)?
确实有。
当您在集合上调用“提取”时,它将响应通过Backbone.Collection.parse传递,然后再将其添加到集合中。
默认的’parse’实现只是按原样传递响应,但是您可以覆盖它以返回要添加到集合中的模型列表:
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
编辑:哇,伊德本特利在我之前到达那儿。唯一的区别是他使用了“每个”,而我使用了“地图”。两者都可以工作,但是有所不同。
使用’each’有效地打破了’fetch’调用开始的链(通过返回’undefined’-随后对’reset’(或’add’)的调用将无济于事)并在解析中在那里进行所有处理功能。
使用“地图”只是将属性列表转换为模型列表,然后将其传递回已经运行的链中。
不同的笔画。
再次编辑:刚刚意识到还有另一种方法:
集合中的’model’属性仅存在,因此,如果集合在’add’,’create’或’reset’中传递了属性,则该集合知道如何制作新模型。因此,您可以执行以下操作:
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'
这样做的好处是,该集合现在将知道如何为“获取”以外的操作“广播” Logbook的正确子类。