ChengLei Shao 24ea83f0ff
Feat/create nocobase app (#273)
* create-nocobase-app template from [develop]

* change create-nocobase-app package.json config

* feat: load configuration from directory

* feat: configuration repository toObject

* feat: create application from configuration dir

* feat: application factory with plugins options

* export type

* feat: read application config &  application with plugins options

* feat: release command

* fix: database release

* chore: workflow package.json

* feat: nocobase cli package

* feat: console command

* chore: load application in command

* fix: load packages from process.cwd

* feat: cli load env file

* feat: create-nocobase-app

* fix: gitignore create-nocobase-app lib

* fix: sqlite path

* feat: create plugin

* chore: plugin files template

* chore: move cli into application

* chore: create-nocobase-app

* fix: create plugin

* chore: app-client && app-server

* chore: package.json

* feat: create-nocobase-app download template from npm

* chore: create-nocobase-app template

* fix: config of plugin-users

* fix: yarn.lock

* fix: database build error

* fix: yarn.lock

* fix: resourcer config

* chore: cross-env

* chore: app-client dependents

* fix: env

* chore: v0.6.0-alpha.1

* chore: verdaccio

* chore(versions): 😊 publish v0.6.0

* chore(versions): 😊 publish v0.6.1-alpha.0

* chore(versions): 😊 publish v0.6.2-alpha.0

* chore(versions): 😊 publish v0.6.2-alpha.1

* chore: 0.6.2-alpha.2

* feat: workspaces

* chore(versions): 😊 publish v0.6.2-alpha.3

* chore(versions): 😊 publish v0.6.2-alpha.4

* chore: create-nocobase-app

* chore: create-nocobase-app lib

* fix: update tsconfig.jest.json

* chore: .env

* chore(versions): 😊 publish v0.6.2-alpha.5

* chore(versions): 😊 publish v0.6.2-alpha.6

* feat: improve code

* chore(versions): 😊 publish v0.6.2-alpha.7

* fix: cleanup

* chore(versions): 😊 publish v0.6.2-alpha.8

* chore: tsconfig for app server package

* fix: move files

* fix: move files

Co-authored-by: chenos <chenlinxh@gmail.com>
2022-04-17 10:00:42 +08:00

4.7 KiB
Raw Blame History

nav, group
nav group
path
/client
path
/client

AsyncDataProvider

利用 Formily 提供的 Effect Hooksx-reactions 协议能一定程度的解决某些场景的异步数据源问题,但是如果只用来处理异步请求,并不会很好用,而且局限于 Formily 体系内。为了更灵活的处理异步请求的各种需求NocoBase 提供了非常好用的可配置化的 useRequest(),用于配置各种异步请求。与此同时,又提供了 <AsyncDataProvider/> 组件,可以将请求结果共享给子组件,方便处理其他更复杂的需求。以平时最常见,但却可能非常复杂的表格为例。表格的使用场景有:

  • TableView 只作为表格视图
  • RowSelection 动态数据的勾选项
  • TableField 表格字段

各自的 schema 可以这么表示:

// 表格视图type 为 void无 default 默认值,无 field.value
// dataSource 直接写在组件的 props 里
{
  type: 'void',
  'x-component': 'TableView',
  'x-component-props': {
    columns: [
      {
        title: 'Name',
        dataIndex: 'name',
        key: 'name',
      },
    ],
    dataSource: [
      { id: 1, name: 'Name1' },
      { id: 2, name: 'Name2' },
    ],
  },
}

// 单选(表格视图),类似于 Radio.Group 字段,可选项由表格视图提供
{
  type: 'number',
  'x-component': 'RowSelection',
  'x-component-props': {
    rowSelection: {
      type: 'radio',
    },
    columns: [
      {
        title: 'Name',
        dataIndex: 'name',
        key: 'name',
      },
    ],
    dataSource: [
      { id: 1, name: 'Name1' },
      { id: 2, name: 'Name2' },
    ],
  },
  default: 1,
}

// 多选(表格视图),类似于 Checkbox.Group 字段,可选项由表格视图提供
{
  type: 'array',
  'x-component': 'RowSelection',
  'x-component-props': {
    rowSelection: {
      type: 'checkbox',
    },
    columns: [
      {
        title: 'Name',
        dataIndex: 'name',
        key: 'name',
      },
    ],
    dataSource: [
      { id: 1, name: 'Name1' },
      { id: 2, name: 'Name2' },
    ],
  },
  default: [1],
}

// 表格字段数据由表单提供schema 层面可以配置默认值
// 与表格视图的方式不同dataSource 和 columns 不适合直接配置在 x-component-props 里,怎么处理先忽略。
{
  type: 'array',
  'x-component': 'TableField',
  'x-component-props': {},
  default: [
    { id: 1, name: 'Name1' },
    { id: 2, name: 'Name2' },
  ],
}

大多数实际应用中,表格视图的 dataSource 是异步获取的,可能也需要过滤和分页,这样一来直接在 x-component-props 里写 dataSource 并不合适。为了解决这个问题,可以给组件扩展一个 request 属性,用于请求远程数据,例子如下:

上述例子的 <TableView/> 组件就是一个 React Component可以正常使用而不局限于 SchemaComponent 场景。更进一步,为了处理过滤表单、分页等问题,建议将 request 通过 <AsyncDataProvider/> 共享给 <TableView/> 组件。

const result = useRequest(props.request);
<AsyncDataProvider value={result}>
  <TableView/>
</AsyncDataProvider>

或者直接将 request 交给 AsyncDataProvider

<AsyncDataProvider request={props.request}>
  <TableView/>
</AsyncDataProvider>

<AsyncDataProvider/> 的子组件里就可以通过 useAsyncData() 来获取 result可用于处理过滤、分页等。

const { data, loading, params, run, refresh, parent } = useAsyncData();

转化为 Schema 时,可以将 AsyncDataProvider 放在 x-decorator 里,也可以将重新组合的 AsyncDataProvider + TableView放在 x-component 里。

将 AsyncDataProvider 独立出来,放到 x-decorator 里的另一个好处,例子如下:

<CollectionProvider>
  {/* 从 CollectionProvider 里获取资源请求参数,并将请求结果同时共享给 DesignableBar 和 TableView */}
  <AsyncDataProvider> 
    <DesignableBar/>
    <TableView>
      <RecordProvider>
        <CollectionFieldProvider>
          {/* 从 CollectionFieldProvider 里获取关系资源请求参数,并将请求结果同时共享给子组件 */}
          <AsyncDataProvider>
            {/* 组件 */}
          </AsyncDataProvider>
        </CollectionFieldProvider>
      </RecordProvider>
    </TableView>
  </AsyncDataProvider>
</CollectionProvider>

上面例子嵌套了两层 AsyncDataProvider在子 AsyncDataProvider 里,也可以获取到更上一级的请求结果,如:

const { parent } = useAsyncData();
parent.refresh();