Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ajax 如何从多个URL填充主干模型_Ajax_Backbone.js - Fatal编程技术网

Ajax 如何从多个URL填充主干模型

Ajax 如何从多个URL填充主干模型,ajax,backbone.js,Ajax,Backbone.js,我想使用一个主干模型,它由来自不同URL端点的数据组成。是否可以在一个模型中指定多个URL?我希望避免手动调用AJAX 到目前为止,我一直在使用调用多个URL并将其结果合成为单个对象 到目前为止,我可以想到两种选择:使用每个URL的部分模型构建主干模型,或者使用一个URL,然后覆盖model.fetch()调用其他URL。但这两个都让我不舒服 (或者我可以贿赂API开发人员提供一个合并的URL端点…我认为您建议的两种方法都很合理,但就个人而言,我会投票支持获取方法 使用嵌套模型具有“开箱即用”的

我想使用一个主干模型,它由来自不同URL端点的数据组成。是否可以在一个模型中指定多个URL?我希望避免手动调用AJAX

到目前为止,我一直在使用调用多个URL并将其结果合成为单个对象

到目前为止,我可以想到两种选择:使用每个URL的部分模型构建主干模型,或者使用一个URL,然后覆盖
model.fetch()
调用其他URL。但这两个都让我不舒服


(或者我可以贿赂API开发人员提供一个合并的URL端点…

我认为您建议的两种方法都很合理,但就个人而言,我会投票支持
获取方法

使用嵌套模型具有“开箱即用”的优点;换句话说,通过对每个服务器-客户端映射使用一个模型,您可以避免更改任何
主干.model
方法。但是,这种方法的问题在于,最终会导致多个模型的聚集

如果这是有意义的(数据检索除外),那么就坚持使用嵌套模型。但如果不是这样的话,那么您将强制您的代码的其余部分使用多个模型,而不仅仅是一个模型,以保持数据检索代码的简单。如果您希望将数据检索代码复杂化,并使其他所有内容保持简单,那么最好覆盖
fetch

fetch
做一件事,那就是通过数据与远程URL之间的一对一映射来检索数据。如果您想要一对多映射,只需覆盖默认的
fetch
行为就非常有意义。另外,您知道重写
获取
是相当安全的,因为它的名称不是
\u fetch
,主干使用下划线样式来命名它的伪私有方法(例如
\u validate

如果您仍然不喜欢这两种方法中的任何一种,那么还有另一种选择:
request
events。最新版本的主干网有一个名为
request
的新事件,每当启动
fetch
时都会触发该事件。这意味着您可以设置一个事件处理程序来检索辅助数据,以响应主数据的请求,如下所示:

Backbone.Model.extend({
    initialize: function() {
        this.on('request', this.handleRequest);
        _.bindAll(this, 'handleTriggeredResponse');
    },
    handleRequest: function() {
        $.ajax({url: secondDataUrl, complete: this.handleTriggeredResponse});
        $.ajax({url: tertiaryDataUrl, complete: this.handleTriggeredResponse});
    },
    handleTriggeredResponse: function(response) {
        this.set(response.data);
    },
    url: firstDataUrl
});

还有另一个解决办法。使用支持URL数组或哈希的高级jquery ajax执行覆盖默认的Backbone.ajax函数。一旦所有请求完成,它将并行加载数据并将控制权传递回主干模型

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
或者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的属性将在一个模型属性中可用。

感谢编辑GammaGames:the
(this)
样式过去是完全可行的,但我想下划线已经从它移开了,我的草率的其他修复也得到了赞赏。