从 backbone.js 中的 json 数组中获取单个模型

fetch single model from json array in backbone.js

我是 Backbone 的新手,所以我可能遗漏了一些明显的东西。但是,我搜索了 Whosebug,但没有找到适合我的问题的内容。

我的模型只有 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}

我错过了什么?


我会建议您更改代码中的一些内容并阅读更多有关 Backbone.Model and Backbone.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.Model 的集合,可以更好地在 Backbone 的方法中进行操作和使用。您可以使用混合 UnderscoreJS 方法对它做任何您想做的事情——过滤、排序、搜索带有 id 的模型等等。

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

当你这样做时:

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

在你的情况下GET '/data/album.json/1'.

,它将触发对以下路由的请求GET '/data/album/1'

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

  1. 更改后端 API 以响应没有 json 扩展名的路由,并且对于单个项目处理路由,例如 /data/album/id

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

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

所以我建议您尝试混合使用第一个和第二个选项。