3.2.5 • Published 4 years ago

tkit-async v3.2.5

Weekly downloads
2
License
MIT
Repository
github
Last release
4 years ago

name: async menu: 'components'

route: /tkit/async

import { Props, Playground } from 'docz'; import Async from './src/Async.tsx'; import Example, { StatusFaker, FormCoreFaker, ModalFaker, FormFaker, ResultTypeFaker, AsyncFaker, AsyncConfirmedFaker } from './tests/Example.tsx';

npm i tkit-async

1. ⚠️ Tips

  • 【自版本 3.2.5 起,解除此限制】npm i tkit-ajax tkit-async tkit-model 确保依赖安装正确
  • 自版本 3.0.4起,doAsync, doAsyncConfirmed返回Promise<fetch函数返回值>

2. 配置 Async 组件

在最顶层组件内引入 Async,监听并展示 async 事件

- 2.1 Async Props

interface AsyncProps

Example

在 Root.tsx 内引入 Async

import React from 'react';
import { Spin, Modal, message } from 'antd';
import Async from 'tkit-async';

// 请在 Root.tsx 内添加
<Async
  form={Form}
  // loading={arg => <Spin spinning={arg.status.isFetch} />}
  sharedLoading={Spin}
  modal={Modal}
  tips={({ type, message: msg }) => message[type](msg)}
/>;

- 2.1.①. form 属性

表单组件,用来渲染表单,并在 model.onOk 时提交表单

class Form extends React.Component<AsyncFormProps> implements AsyncForm {}

interface AsyncFormProps

interface AsyncForm

Example

export class FormFaker extends React.Component<AsyncFormProps> implements AsyncForm {
  public static fakeData = {
    name: 'skipper'
  };
  public constructor(props: AsyncFormProps) {
    super(props);
    if (props.getForm) {
      props.getForm(this);
    }
  }
  public submit() {
    return FormFaker.fakeData;
  }
  public render() {
    return <div>nihao</div>;
  }
}

- 2.1.②. Deprecatedloading 属性

【废弃,用 sharedLoading 替代】显示加载效果的组件

  interface loading {
    (arg: AsyncStatus) => any;
  }

interface AsyncStatus

Example

(arg: AsyncStatus) => <Spin spinning={arg.status.isFetch} />;

- 2.1.③. sharedLoading 属性

全局加载效果组件【所有 effect 共用一个效果】版本 3.0.6+ 开始支持

Example
() => 'loading';

- 2.1.④. modal 属性

弹窗组件,可直接使用 antd Modal 或自定义

class Modal extends React.Component<AsyncModalProps> {}

interface AsyncModalProps

Example

export class ModalFaker extends React.Component<AsyncModalProps> {
  public render() {
    const { visible, title, content, className, confirmLoading, onOk, onCancel } = this.props;
    return <div>{content}</div>;
  }
}

- 2.1.⑤. tips 属性

成功、错误提示函数

interface tips {
  (msg: AsyncResultEventType) => void;
}

interface AsyncResultEventType

Example

 const message = { error: () => 0, success: () => 1 }
 ({ type, message: msg }: AsyncResultEventType) => message[type](msg);

3. API

触发 async 事件的接口

import { doAsync, doAsyncConfirmed, useAsyncStatus } from 'tkit-async';

- 3.1. doAsync

自版本 tkit-async@3.0.6 & tkit-service@3.0.14 & tkit-ajax@3.0.4 以上,可以取消请求

- 3.1.① doAsync 参数

interface IAsyncActionProps

Example

doAsync(<IAsyncActionProps<any>>{ ... })

Example Cancel

import { promiseFactory } from 'tkit-ajax';

const [{ resolve }, cancel] = promiseFactory<string>();
const res = yield doAsync({
  fetch: naotu.doModifyDoc,
  ...,
  paramsGenerator: ({ extraParams }) => [
    {
      doc: {
        ...extraParams
      }
    },
    {
      cancel
    }
  ],
  onCancel: () => {
    resolve('放弃了');
  },
  ...
});

- 3.2. doAsyncConfirmed

- 3.2.① doAsyncConfirmed 参数

interface IAsyncConfirmedParams

Example

doAsyncConfirmed(<IAsyncConfirmedParams<any>>{ ... })

- 3.3. useAsyncStatus

自版本 3.0.5 起支持——定制组件局部的 loading 效果——注意:需要再容器内局部显示 loading 效果的,请勿将 model effects 配置 loading,否则也会显示全局 loading 效果

Example

import { useAsyncStatus } from 'tkit-async';

const Cp = () => {
  const [status] = useAsyncStatus(
    (status: AsyncStatus) => status.effectName === 'docModel/getDocList'
  );

  return status ? 'loading' : null;
};

4. Example

Example Source Code

import React from 'react';
import { Spin, Modal, Button, Input, message } from 'antd';
import { AjaxPromise, TkitAjaxFunction } from 'tkit-ajax';
import { AsyncResultEventType, doAsync, doAsyncConfirmed, Async } from 'tkit-async';

// @IMP: 表单组件
export class FormFaker extends React.Component<AsyncFormProps> {
  public static fakeData = {
    name: 'skipper'
  };
  public constructor(props: AsyncFormProps) {
    super(props);
    if (props.getForm) {
      props.getForm(this);
    }
  }
  public submit() {
    return FormFaker.fakeData;
  }
  public render() {
    return <div>nihao</div>;
  }
}

const loadData = (id: number): AjaxPromise<any> => {
  console.log('running effect');
  return new Promise((rs, rj) => {
    setTimeout(() => rs({ code: 0, message: '逗我呢', result: { id } }), 1000);
  });
};

export default function Example() {
  return (
    <div>
      <Async
        form={FormFaker}
        loading={arg => <Spin spinning={arg.status.isFetch} />}
        modal={Modal}
        tips={({ type, message: msg }) => message[type](msg)}
      />
      <Button
        onClick={() => {
          doAsync({
            fetch: loadData,
            callback: console.log,
            modalProps: {
              title: 'nihao',
              content: (
                <div>
                  <Input />
                  <Button
                    onClick={() => {
                      doAsync({
                        fetch: loadData,
                        modalProps: {
                          content: '你好',
                          title: '2'
                        }
                      });
                    }}
                  >
                    嵌套了
                  </Button>
                </div>
              )
            }
          });
        }}
      >
        弹窗测试
      </Button>
      &nbsp;
      <Button
        onClick={() => {
          doAsyncConfirmed({
            fetch: loadData,
            callback: console.log
          });
        }}
      >
        不弹窗带loading测试
      </Button>
      &nbsp;
      <Button
        onClick={() => {
          doAsyncConfirmed({
            fetch: loadData,
            callback: console.log,
            indicator: null
          });
        }}
      >
        不显示loading测试
      </Button>
    </div>
  );
}