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: ...}
]

我想在客户端复制这个服务器模型,所以我有一个基本的Logbook类和多个日志(log)子类:

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.

使用"each"可以有效地断开"fetch"调用启动的链(通过返回"undefined"——因此对"reset"(或"add")的后续调用将不起任何作用),并在解析函数中执行所有处理.

使用"映射"只是将属性列表转换为模型列表,并将其传递回已经在运动的链.

不同的笔划.

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'.

Json相关问答推荐

如何将自定义卡保存到dart/flutter中的共享偏好设置?

合并二维数组的Jolt表达式

如何在我的响应模型中修复此问题:[期望的值类型为';Map<;Dynamic,Dynamic&>;,但获得的值类型为';NULL&39;]

对一些JSON模式验证的混淆

重构JOLT代码以获得预期输出

如何在Android中解析带有动态键和可变对象名称的改装JSON响应?

在 python 中循环 JSON 数组

PowerShell - 将 json 添加到文件内容

如何在 Apps 脚本中循环遍历 JSON 响应

用于遮蔽卡的 Jolt 规格

派生类的属性没有得到价值

Powershell 7.2:ConvertFrom-Json - 日期处理

使用 KQL 和外部 data() 运算符从 json 文件中提取信息

如何使用 React 从 NASA IMAGES API 中解构所需信息

如何使用 boost::json::value 调用无参数函数

将嵌套的 JSON 对象规范化为 Pandas 数据框

如何判断 Json 对象中是否存在键并获取其值

Spring MVC控制器中的JSON参数

如何在 JAVA 中对 JSONArray 进行排序

类型是接口或抽象类,不能实例化