js-datav3-将元信息保存在分页的端点中

js-data v3- Keeping meta information in a paginated end point

本文关键字:分页 端点 存在 保存 信息 js-datav3-      更新时间:2023-09-26

我正在尝试反序列化分页的端点。此终点的退货请求看起来像

{
    count: number,
    next: string,
    previous: string,
    data: Array[Objects]
}

我在使用js数据执行findAll时遇到的问题是,它将这个对象注入到数据存储中。它应该将数据数组中的对象注入到存储中。因此,我在适配器上制作了一个反序列化方法,如下所示。

deserialize: (resourceConfig:any, response:any) => {
  let data = response.data;
  if (data && 'count' in data && 'next' in data && 'results' in data) {
    data = data.results;
    data._meta = {
      count: response.data.count,
      next: response.data.next,
      previous: response.data.previous
    };
  }
  return data;
}

这是有效的。数组对象正在被注入到我的数据存储中。但元信息正在丢失。

dataStore.findAll('User').then(r => console.log(r._meta)); // r._meta == undefined

我想保留返回对象的元信息。有什么想法吗?

要在v3中做到这一点,只需要覆盖几个方法来调整JSData的处理来自分页端点的响应。两个最重要的事情是告诉JSData响应的哪个嵌套属性是记录以及应将哪个嵌套属性添加到内存存储中(应为两种情况下的嵌套属性相同)。

示例:

const store = new DataStore({
  addToCache: function (name, data, opts) {
    if (name === 'post' && opts.op === 'afterFindAll') {
      // Make sure the paginated post records get added to the store (and
      // not the whole page object).
      return DataStore.prototype.addToCache.call(this, name, data.results, opts);  
    }
    // Otherwise do default behavior
    return DataStore.prototype.addToCache.call(this, name, data, opts);
  }
});
store.registerAdapter('http', httpAdapter, { 'default': true });
store.defineMapper('post', {
  // GET /posts doesn't return data as JSData expects, so we've got to tell
  // JSData where the records are in the response.
  wrap: function (data, opts) {
    // Override behavior of wrap in this instance
    if (opts.op === 'afterFindAll') {
      // In this example, the Post records are nested under a "results"
      // property of the response data. This is a paginated endpoint, so the
      // response data might also have properties like "page", "count",
      // "hasMore", etc.
      data.results = store.getMapper('post').createRecord(data.results);
      return data
    }
    // Otherwise do default behavior
    return Mapper.prototype.wrap.call(this, data, opts);
  }
});
// Example query, depends on what your backend expects
const query = { status: 'published', page: 1 };
posts.findAll(query)
  .then((response) => {
    console.log(response.results); // [{...}, {...}, ...]
    console.log(response.page); // 1
    console.log(response.count); // 10
    console.log(response.hasMore); // true
  });