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

时间:2015-10-29 08:05:06

标签: jsdata js-data-angular

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

然而,

  • 当我使用find时,js-data与可怕的[Error] "attrs" must be an object!一起死亡,因为它需要1行,否则无法说服 - 除非我遗漏了什么。
  • 当我使用findAll时,我需要使用uglier /report/?categoryId = 22进行搜索 - 并更改服务器
  • 当我使用动作时,它会将动作名称附加到URI,这是我不需要的,例如: /report/22/myaction

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

  • 有一个干净的网址
  • 加载数据数组
  • 最好不要更改服务器实现

1 个答案:

答案 0 :(得分:1)

本回答中的所有内容都假定您正在使用HTTP适配器。

JSData的默认预期如下:

  • GET /<resource>/:id返回一个对象,例如{ id: 1 }
  • GET /<resource>返回一个对象数组,例如[{ id: 1 }, { id: 2 }]
  • POST /<resource> { some: 'field' }在您的数据库中创建一个项目 并返回更新的项目,例如{ id: 1, some: 'field' }
  • PUT /<resource>/:id { updated: 'field' }更新您的个人资料 数据库并返回更新的项目,例如{ id: 1, updated: 'field' }
  • PUT /<resource> { updated: 'field' }更新您的收藏品 数据库并返回更新的项目,例如[{ 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. 返回最终结果
  5. 避免注射错误的唯一方法是:

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

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

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

    DS#inject要求对象具有由...指定的字段 资源的idAttribute选项或相同的数组。

    您有三次机会在数据到达DS#inject之前按摩数据:

    1. HTTP响应拦截器
    2. deserialize hook
    3. afterFindafterFindAll挂钩
    4. 在任何一种方法中,您都可以将数据修复为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资源一起使用 对应于数据库中的表和资源的实例对应 表中的行。生成报告通常是其中之一 您从不同的来源编辑数据,进行聚合等等 不可预测(因此,这个问题)。

      这是另一种选择:

      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(); // [{...}, {...}]
      });
      

      基本上,有很多方法可以完成任何特定的任务,每个任务都有它 自己的利弊。 JSData只能通过它来推广到这么多的用例 默认设置。

      要解锁JSData的强大功能并最大限度地提高您的工作效率,您需要这样做 注意JSData中的许多选项和钩子,它们可以模拟JSData 按照你的喜好。如果您发现任何特定的扩展或自定义 你所撰写的文章可以被概括,并使很多其他人有所帮助 相同的用例,let us know

      干杯!