跳到主要内容

schema.Array

创建一个用于规范化 schema 数组的 schema。如果输入值是 Object 而不是 Array,规范化的结果将是由该 Object 的值组成的 Array。

注意:同样的行为也可以用简写语法定义:[ mySchema ]

  • definition:必填 该数组所包含的单个 schema,_或_属性值到 schema 的映射。
  • schemaAttribute:可选(当 definition 不是单个 schema 时必填)每个 Entity 上的一个属性,根据 definition 映射决定规范化时使用哪个 schema。可以是字符串或函数。如果是函数,它接收以下参数: _ value:该 Entity 的输入值。 _ parent:输入数组的父对象。* key:输入数组在父对象上所处的键。
提示

对于以 string 为键的无界集合,请使用 schema.Values

提示

使用 Collections 让它变为可变的(可以 push/unshift 新条目)

实例方法​

  • define(definition):调用时,传入的 definition 会与传给 Array 构造函数的原始 definition 合并。此方法通常用于在 schema 中创建循环引用。

用法​

描述由单一 Entity 类型组成的简单数组:

Fixtures
GET /users
[{"id":"123","name":"Jim"},{"id":"456","name":"Jane"}]
▶Users.tsx
import { Entity, RestEndpoint, schema } from '@data-client/rest';
import { useSuspense } from '@data-client/react';

export class User extends Entity {
  id = '';
  name = '';
}
export const getUsers = new RestEndpoint({
  path: '/users',
  schema: new schema.Array(User),
});
function UsersPage() {
  const users = useSuspense(getUsers);
  return (
    <div>
      {users.map(user => (
        <div key={user.pk()}>{user.name}</div>
      ))}
    </div>
  );
}
render(<UsersPage />);
结果
Store▶

更新多个 Entity​

将 Array 与 Controller.set() 配合使用,无需 endpoint,即可在一次 store 更新中写入多个 Entity。

ctrl.set(
[User],
[
{ id: '123', name: 'Jim' },
{ id: '456', name: 'Jane' },
],
);

多态类型​

如果输入数据是包含多种 Entity 类型的数组,就需要定义 schema 映射。

备注

如果数据中返回了你没有提供映射的对象,结果中会返回原始对象,并且不会创建 Entity。

字符串形式的 schemaAttribute​

Fixtures
GET /feed
[{"id":1,"type":"link","url":"https://ntucker.true.io","title":"Nate site"},{"id":10,"type":"post","content":"good day!"}]
▶api/Feed
import { Entity, RestEndpoint, schema } from '@data-client/rest';

export abstract class FeedItem extends Entity {
  readonly id: number = 0;
  declare readonly type: 'link' | 'post';
}
export class Link extends FeedItem {
  readonly type = 'link' as const;
  readonly url: string = '';
  readonly title: string = '';
}
export class Post extends FeedItem {
  readonly type = 'post' as const;
  readonly content: string = '';
}
export const getFeed = new RestEndpoint({
  path: '/feed',
  schema: new schema.Array(
    {
      link: Link,
      post: Post,
    },
    'type',
  ),
});
▶FeedList
结果
Store▶

函数形式的 schemaAttribute​

返回值应与 definition 中的某个键匹配。这里展示与“字符串”情形相同的行为,只是会在末尾追加一个 's'。

Fixtures
GET /feed
[{"id":1,"type":"link","url":"https://ntucker.true.io","title":"Nate site"},{"id":10,"type":"post","content":"good day!"}]
▶api/Feed
import { Entity, RestEndpoint, schema } from '@data-client/rest';

export abstract class FeedItem extends Entity {
  readonly id: number = 0;
  declare readonly type: 'link' | 'post';
}
export class Link extends FeedItem {
  readonly type = 'link' as const;
  readonly url: string = '';
  readonly title: string = '';
}
export class Post extends FeedItem {
  readonly type = 'post' as const;
  readonly content: string = '';
}
export const getFeed = new RestEndpoint({
  path: '/feed',
  schema: new schema.Array(
    {
      links: Link,
      posts: Post,
    },
    (input: Link | Post, parent: unknown, key: string) => `${input.type}s`,
  ),
});
▶FeedList
结果
Store▶