如何让 find() 接受一个数组而不是一个对象?

How to make find() accept an array instead of one object?

在 Angular 中使用 JS-Data 2.6,我正在尝试使用干净的 URL 加载一组数据,例如/report/22。 (这种格式很有意义,因为它遵循业务逻辑 - 我正在按类别 ID 加载报告数据,然后返回几行。)

然而,

有没有办法使用 find() 或 findAll() 来

此答案中的所有内容均假定您使用的是 HTTP 适配器。

JSData 的默认期望如下:

  • GET /<resource>/:id returns 一个对象,例如{ id: 1 }
  • GET /<resource> returns 一组对象,例如[{ id: 1 }, { id: 2 }]
  • POST /<resource> { some: 'field' } 在您的数据库中创建一个项目 和 returns 更新的项目,例如{ id: 1, some: 'field' }
  • PUT /<resource>/:id { updated: 'field' } 更新您的单个项目 数据库和 returns 更新的项目,例如{ id: 1, updated: 'field' }
  • PUT /<resource> { updated: 'field' } 更新您的项目集合 数据库和 returns 更新的项目,例如[{ id: 1, updated: 'field' }, { id: 2, updated: 'field' }] -DELETE /<resource>/:id 从您的数据库中删除一个项目
  • DELETE /<resource> 从您的数据库中删除项目集合

默认情况下,DS#find GET /<resource>/:idDS#findAll GET /<resource>.

来自服务器的任何响应在收到时都需要采用正确的格式 至 DS#inject.

这些调用的生命周期如下:

  1. 调用适配器的findfindAll方法
    1. 调用适配器的GET方法
    2. 调用适配器的HTTP方法
    3. 在服务器响应时调用 deserialize 方法
  2. 将适配器响应传递给 afterFindafterFindAll 挂钩
  3. 勾选cacheResponse
    1. 如果true,将afterFindafterFindAll的结果传递给DS#inject
    2. 如果false,将afterFindafterFindAll的结果传递给DS#createInstance
  4. Return最终结果

避免注入错误的唯一方法是:

A) 不将适配器响应注入数据存储

B) 在将数据传递到 DS#inject

之前将数据按正确的格式处理

DS#inject 需要一个具有由 资源的 idAttribute 选项,或相同的数组。

在数据到达 DS#inject:

之前,您有 3 次修改数据的机会
  1. HTTP 响应拦截器
  2. deserialize 挂钩
  3. afterFindafterFindAll 挂钩

在这些方法中的任何一种中,您都可以将数据修复为 DS#inject 期待。

如果你希望能够做到 Report.find(22) 那么你可以做到:

var Report = store.defineResource({
  name: 'report',
  afterFind: function (Report, data, cb) {
    cb(null, {
      id: 22,
      data: data
    });
  }
});

Report.find(22).then(function (report) {
  report.id; // 22
  report.data; // [{...}, {...}]
});

所有这些都假定您确实希望能够使用 DS#find,但是 DS#findDS#findAll 旨在与 RESTful 资源一起使用,其中资源 对应于数据库中的 table 并且 Resource 的实例对应于 table 中的行。生成报告通常是其中之一 你正在编译来自不同来源的数据,进行聚合等。它是 不像 predictable(因此,这个问题)。

还有一个选项:

var Report = store.defineResource({
  name: 'report',

  /* Static Class Methods */
  findByCategoryId: function (id) {
    // Use the adapter directly
    return Report.getAdapter('http').find(Report, id).then(function (data) {
      // Inject the result into the store
      return Report.inject({
        id: 22,
        data: data
      });
    });
  }
});

Report.findByCategoryId(22). then(function (report) {
  return Report.findByCategoryId(23);
}).then(function (report) {
  Report.filter(); // [{...}, {...}]
});

基本上,有许多方法可以完成任何特定任务,每种方法都有其 自己的一套pros/cons。 JSData 只能泛化到这么多用例 默认设置。

要释放 JSData 的力量并最大限度地提高您的工作效率,您需要 注意 JSData 中的许多选项和挂钩,它们允许您塑造 JSData 随你喜欢。如果您发现任何特定的扩展或自定义 你写的可以推广并使很多其他拥有 相同的用例,let us know!

干杯!