【问题标题】:fetch single model from json array in backbone.js从backbone.js中的json数组中获取单个模型
【发布时间】:2026-02-21 11:15:01
【问题描述】:

我对 Backbone 很陌生,所以我可能会遗漏一些明显的东西。但是,我搜索了 * 并没有找到任何适合我的问题。

我的模型只有 urlRoot:

Album = Backbone.Model.extend({
    urlRoot: '/data/album.json'
});

json 看起来像这样:

[{
  "id": "01",
  "title": "title1",
  "artist": "artist1",
  "tracks": [{
    "track": "track1",
    "url": "/music/101.mp3"
  },
  {
    "track": "track2",
    "url": "/music/102.mp3"
  }]
},
{
  "id": "02",
  "title": "title2",
  "artist": "artist2",
  "tracks": [{
    "track": "track1",
    "url": "/music/201.mp3"
  },
  {
    "track": "track2",
    "url": "/music/202.mp3"
  }]
}]

我能够获取数组中的对象:

album = new Album();
album.fetch();
album.toJSON(); --> //Object {0: Object, 1: Object}

在我的新模型上调用 toJSON 表明该数组已正确获取。如果我展开每个对象,我会看到所有属性。

但是,当我尝试从数组中仅获取单个对象时,它不起作用。

album = new Album({id: 01});
album.fetch()
album.toJSON(); --> // Object {id: 1}

我错过了什么?


【问题讨论】:

  • 您是否配置了后端 API 以响应 /data/album/1.json 之类的路由?
  • 您解决了这个问题吗?
  • 是的,两个 cmets 都为我指明了正确的方向。

标签: arrays json backbone.js model fetch


【解决方案1】:

我建议您更改代码中的一些内容,并详细了解Backbone.ModelBackbone.Collection 以及 REST-ful 资源的行为方式。


在处理对象集合或所谓的资源(来自 REST)时,尝试使用 Backbone.Collection。并在该集合中提及适当的Backbone.Model,它将代表您集合中的单个项目。在您的情况下,/data/album 是资源。


为了演示它,让我们将您的示例更改为以下内容(我将使用不带 json 扩展名的路由):

var Album = Backbone.Model.extend({
    urlRoot: '/data/album', 
    // mention here defaults hash, add parse method if you need to change response
    // from backend, add validations, add idAttribute if the name of 
    // unique identifier is not the id 
});

var Albums = Backbone.Collection.extend({
    url: '/data/album', 
    model: Album
});

var albums = new Albums();
albums.fetch();

现在您已经收集了Backbone.Models,它在 Backbone 的方法中更易于操作和使用。您可以使用混合的 UnderscoreJS 方法对它做任何您想做的事情 - 过滤、排序、搜索带有 id 的模型等等。

当您需要获取资源的单个模型或单个项目时,您需要了解Backbone.Model 将如何更改路由 (urlRoot)。

当你这样做时:

var album = new Album({id: 1});
var album.fetch(); 

在您的情况下,它将触发对以下路由 GET '/data/album/1' 的请求 GET '/data/album.json/1'


您有几个选项可以解决您的问题:

  1. 更改后端 API 以响应不带 json 扩展名的路由以及 /data/album/id 等单项处理路由

  2. 重写Backbone.Model将id连接到url的方式。你可以重写Backbone.Modelurl函数来支持带扩展的路由。

  3. 如果你不能触摸后端(最糟糕的方式),你可以保留你的旧实现并添加一些解决方法,比如将 parse 方法添加到 Backbone.Model .... 实际上它会开始表现就像 Backbone.Collection,因为任何时候您需要单个项目,您都需要获取所有的东西并在混乱中找到所需的对象。

所以我建议你尝试第一个和第二个选项的混合。

【讨论】: