还有另一种解决方案。使用支持数组或 url 哈希的高级 jquery ajax 执行覆盖默认 Backbone.ajax 函数。一旦所有请求完成,它将并行加载数据并将控制权传递回 Backbone 模型。
ajaxForArray = ->
options = _.first arguments
$.when.apply $, options.url.map (url) ->
$.ajax _.merge _.omit(options, ['url', 'success']), {url}
.done ->
resp =
if options.url.length > 1
_.slice(arguments).map (arg) -> _.first arg
else
_.first arguments
options.success? resp
ajaxForHash = ->
options = _.first arguments
pairs = _.transform options.url, (memo, url, key) ->
memo.push {key, url}
, []
$.when.apply $, pairs.map (pair) ->
$.ajax _.merge _.omit(options, ['url', 'success']), url: pair.url
.done ->
resp = _.slice(arguments).reduce (memo, arg, i) ->
memo[pairs[i].key] = _.first arg
memo
, {}
options.success? resp
Backbone.ajax = ->
options = _.first arguments
if _.isArray options.url
ajaxForArray.apply $, arguments
else if _.isObject(options.url) and not _.isFunction options.url
ajaxForHash.apply $, arguments
else
$.ajax.apply $, arguments
现在可以使用 URL 数组设置模型,例如
class ArrayBasedModel extends Backbone.Model
url: ['/aoo', '/boo', '/coo']
parse: (resp) ->
super _.extend {}, resp[0], resp[1], resp[2]
或网址的哈希值,例如
class HashBasedModel extends Backbone.Model
url: {aoo: '/aoo', boo: '/boo', coo: '/coo'}
parse: (resp) ->
super _.extend {}, resp.aoo, resp.boo, resp.coo
因此,当 parse() 被覆盖时,只需添加一些合并所有 ajax 调用结果的基本逻辑,以将其传递给 Backbone.Model.parse()。
毕竟,来自不同 URL 的属性将在一个模型属性中可用。