mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-30 02:58:05 +08:00
Merge pull request #8506 from miaoxinyu01/feat-change-event
feat:富文本和分页组件事件面板新增change事件
This commit is contained in:
commit
4c8ac88aeb
@ -230,3 +230,12 @@ froala 可以通过设置 buttons 参数来控制显示哪些按钮,默认是
|
||||
| size | `string` | | 框的大小,可设置为 `md` 或者 `lg` |
|
||||
| options | `object` | | 需要参考 [tinymce](https://www.tiny.cloud/docs/configure/integration-and-setup/) 或 [froala](https://www.froala.com/wysiwyg-editor/docs/options) 的文档 |
|
||||
| buttons | `Array<string>` | | froala 专用,配置显示的按钮,tinymce 可以通过前面的 options 设置 [toolbar](https://www.tiny.cloud/docs/demo/custom-toolbar-button/) 字符串 |
|
||||
|
||||
## 事件表
|
||||
|
||||
当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
|
||||
|
||||
> `[name]`表示当前组件绑定的名称,即`name`属性,如果没有配置`name`属性,则通过`value`取值。
|
||||
> | 事件名称 | 事件参数 | 说明 |
|
||||
> | -------- | ------------------------------------- | ------------------------------------------- |
|
||||
> | change | `[value]: object` 富文本组件的值<br/> | 富文本值改变时触发 |
|
||||
|
@ -67,3 +67,10 @@ order: 73
|
||||
| showPageInput | `boolean` | false | 是否显示快速跳转输入框 layout 和 showPageInput 都可以控制 |
|
||||
| disabled | `boolean` | false | 是否禁用 |
|
||||
| onPageChange | page、perPage 改变时会触发 | (page: number, perPage: number) => void; | 分页改变触发 |
|
||||
|
||||
当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
|
||||
|
||||
> `[name]`表示当前组件绑定的名称,即`name`属性,如果没有配置`name`属性,则通过`value`取值。
|
||||
> | 事件名称 | 事件参数 | 说明 |
|
||||
> | -------- | ------------------------------------- | ------------------------------------------- |
|
||||
> | change | `[value]: object` 当前页码的值<br/> | 当前页码值改变时触发 |
|
@ -2,11 +2,12 @@ import {
|
||||
BaseEventContext,
|
||||
getSchemaTpl,
|
||||
defaultValue,
|
||||
RendererPluginEvent,
|
||||
tipedLabel
|
||||
} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin} from 'amis-editor-core';
|
||||
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
|
||||
const tinymceToolbarsDelimiter = ' ';
|
||||
@ -183,6 +184,32 @@ export class RichTextControlPlugin extends BasePlugin {
|
||||
|
||||
panelTitle = '富文本';
|
||||
|
||||
events: RendererPluginEvent[] = [
|
||||
{
|
||||
eventName: 'change',
|
||||
eventLabel: '值变化',
|
||||
description: '输入内容变化',
|
||||
dataSchema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
data: {
|
||||
type: 'object',
|
||||
title: '数据',
|
||||
properties: {
|
||||
value: {
|
||||
type: 'string',
|
||||
title: '富文本的值'
|
||||
}
|
||||
},
|
||||
description: '当前数据域,可以通过.字段名读取对应的值'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
notRenderFormZone = true;
|
||||
|
||||
panelJustify = true;
|
||||
@ -432,6 +459,16 @@ export class RichTextControlPlugin extends BasePlugin {
|
||||
getSchemaTpl('style:classNames')
|
||||
])
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '事件',
|
||||
className: 'p-none',
|
||||
body: [
|
||||
getSchemaTpl('eventControl', {
|
||||
name: 'onEvent',
|
||||
...getEventControlConfig(this.manager, context)
|
||||
})
|
||||
]
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
@ -1,15 +1,15 @@
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
RegionConfig,
|
||||
BaseEventContext,
|
||||
tipedLabel
|
||||
tipedLabel,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
RendererPluginEvent,
|
||||
registerEditorPlugin
|
||||
} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../validator';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {RendererPluginEvent} from 'amis-editor-core';
|
||||
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
|
||||
export class PaginationPlugin extends BasePlugin {
|
||||
static id = 'PaginationPlugin';
|
||||
@ -49,6 +49,32 @@ export class PaginationPlugin extends BasePlugin {
|
||||
};
|
||||
panelTitle = '分页器';
|
||||
|
||||
events: RendererPluginEvent[] = [
|
||||
{
|
||||
eventName: 'change',
|
||||
eventLabel: '值变化',
|
||||
description: '输入内容变化',
|
||||
dataSchema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
data: {
|
||||
type: 'object',
|
||||
title: '数据',
|
||||
properties: {
|
||||
value: {
|
||||
type: 'string',
|
||||
title: '当前页码值'
|
||||
}
|
||||
},
|
||||
description: '当前数据域,可以通过.字段名读取对应的值'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
panelJustify = true;
|
||||
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import isInteger from 'lodash/isInteger';
|
||||
import {localeable, LocaleProps} from 'amis-core';
|
||||
import {localeable, LocaleProps, resolveEventData} from 'amis-core';
|
||||
import {themeable, ThemeProps} from 'amis-core';
|
||||
import {autobind} from 'amis-core';
|
||||
import {Icon} from './icons';
|
||||
@ -93,7 +93,8 @@ export interface BasicPaginationProps {
|
||||
*/
|
||||
popOverContainerSelector?: string;
|
||||
|
||||
onPageChange?: (page: number, perPage?: number) => void;
|
||||
onPageChange?: (page: number, perPage?: number, dir?: string) => void;
|
||||
dispatchEvent?: Function;
|
||||
}
|
||||
export interface PaginationProps
|
||||
extends BasicPaginationProps,
|
||||
@ -139,13 +140,22 @@ export class Pagination extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
handlePageNumChange(page: number, perPage?: number) {
|
||||
const {disabled, onPageChange} = this.props;
|
||||
async handlePageNumChange(page: number, perPage?: number, dir?: string) {
|
||||
const {disabled, onPageChange, dispatchEvent} = this.props;
|
||||
const _page = isNaN(Number(page)) || Number(page) < 1 ? 1 : page;
|
||||
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
onPageChange?.(isNaN(Number(page)) || Number(page) < 1 ? 1 : page, perPage);
|
||||
|
||||
const rendererEvent = await dispatchEvent?.(
|
||||
'change',
|
||||
resolveEventData(this.props, {_page})
|
||||
);
|
||||
if (rendererEvent?.prevented) {
|
||||
return;
|
||||
}
|
||||
onPageChange?.(_page, perPage, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,159 @@
|
||||
import {fireEvent, render} from '@testing-library/react';
|
||||
import '../../../src';
|
||||
import {render as amisRender} from '../../../src';
|
||||
import {makeEnv, wait} from '../../helper';
|
||||
|
||||
test('pagination: pageNum change event', async () => {
|
||||
const mockFn = jest.fn();
|
||||
const pageChange = jest.fn();
|
||||
const {container} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'pagination',
|
||||
layout: 'total,perPage,pager,go',
|
||||
mode: 'normal',
|
||||
activePage: 2,
|
||||
lastPage: 99999,
|
||||
total: 999,
|
||||
perPage: 10,
|
||||
maxButtons: 7,
|
||||
showPerPage: true,
|
||||
perPageAvailable: [10, 20, 50, 100],
|
||||
showPageInput: true,
|
||||
disabled: false,
|
||||
id: 'u:1bf323bc4dbd',
|
||||
onPageChange: pageChange,
|
||||
onEvent: {
|
||||
change: {
|
||||
weight: 0,
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
script: mockFn
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{},
|
||||
makeEnv({})
|
||||
)
|
||||
);
|
||||
// 当前页码改变
|
||||
const prev = container.querySelector('.cxd-Pagination-prev')!;
|
||||
fireEvent.click(prev); // 上一页
|
||||
await wait(100);
|
||||
expect(mockFn).toBeCalledTimes(1);
|
||||
await wait(200);
|
||||
expect(pageChange).toBeCalled();
|
||||
expect(pageChange.mock.calls[0]).toEqual([1, 10]);
|
||||
|
||||
const next = container.querySelector('.cxd-Pagination-next')!;
|
||||
fireEvent.click(next); // 下一页
|
||||
await wait(300);
|
||||
expect(mockFn).toBeCalledTimes(2);
|
||||
await wait(200);
|
||||
expect(pageChange).toBeCalled();
|
||||
expect(pageChange.mock.calls[1]).toEqual([3, 10]);
|
||||
|
||||
const go = container.querySelector('.cxd-Pagination-inputGroup')!;
|
||||
fireEvent.change(go.querySelector('.cxd-Pagination-inputGroup-input')!, {
|
||||
target: {value: 9}
|
||||
});
|
||||
await wait(400);
|
||||
fireEvent.click(go.querySelector('.cxd-Pagination-inputGroup-right')!); // 输入后点击go
|
||||
await wait(500);
|
||||
expect(mockFn).toBeCalledTimes(3);
|
||||
await wait(200);
|
||||
expect(pageChange).toBeCalled();
|
||||
expect(pageChange.mock.calls[2]).toEqual([9, 10]);
|
||||
|
||||
function getPagerItem() {
|
||||
const pager = container.querySelectorAll(
|
||||
'.cxd-Pagination > .cxd-Pagination-pager-item'
|
||||
);
|
||||
return pager[3];
|
||||
}
|
||||
fireEvent.click(getPagerItem()!); // 点击页码切换
|
||||
await wait(600);
|
||||
expect(mockFn).toBeCalledTimes(4);
|
||||
await wait(200);
|
||||
expect(pageChange).toBeCalled();
|
||||
expect(pageChange.mock.calls[3]).toEqual([4, 10]);
|
||||
});
|
||||
|
||||
test('pagination: prevent pageNum change event ', async () => {
|
||||
const mockFn = jest.fn();
|
||||
const pageChange = jest.fn();
|
||||
const {container} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'pagination',
|
||||
layout: 'total,perPage,pager,go',
|
||||
mode: 'normal',
|
||||
activePage: 2,
|
||||
lastPage: 99999,
|
||||
total: 999,
|
||||
perPage: 10,
|
||||
maxButtons: 7,
|
||||
showPerPage: true,
|
||||
perPageAvailable: [10, 20, 50, 100],
|
||||
showPageInput: true,
|
||||
disabled: false,
|
||||
id: 'u:1bf323bc4dbd',
|
||||
onPageChange: pageChange,
|
||||
onEvent: {
|
||||
change: {
|
||||
weight: 0,
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
preventDefault: true, // 阻止事件默认行为
|
||||
script: mockFn
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{},
|
||||
makeEnv({})
|
||||
)
|
||||
);
|
||||
// 当前页码改变
|
||||
const prev = container.querySelector('.cxd-Pagination-prev')!;
|
||||
fireEvent.click(prev); // 上一页
|
||||
await wait(100);
|
||||
expect(mockFn).toBeCalledTimes(1);
|
||||
await wait(200);
|
||||
expect(pageChange).not.toBeCalled();
|
||||
|
||||
const next = container.querySelector('.cxd-Pagination-next')!;
|
||||
fireEvent.click(next); // 下一页
|
||||
await wait(300);
|
||||
expect(mockFn).toBeCalledTimes(2);
|
||||
await wait(200);
|
||||
expect(pageChange).not.toBeCalled();
|
||||
|
||||
const go = container.querySelector('.cxd-Pagination-inputGroup')!;
|
||||
fireEvent.change(go.querySelector('.cxd-Pagination-inputGroup-input')!, {
|
||||
target: {value: 9}
|
||||
});
|
||||
await wait(400);
|
||||
fireEvent.click(go.querySelector('.cxd-Pagination-inputGroup-right')!); // 输入后点击go
|
||||
await wait(500);
|
||||
expect(mockFn).toBeCalledTimes(3);
|
||||
await wait(200);
|
||||
expect(pageChange).not.toBeCalled();
|
||||
|
||||
function getPagerItem() {
|
||||
const pager = container.querySelectorAll(
|
||||
'.cxd-Pagination > .cxd-Pagination-pager-item'
|
||||
);
|
||||
return pager[3];
|
||||
}
|
||||
fireEvent.click(getPagerItem()!); // 点击页码切换
|
||||
await wait(600);
|
||||
expect(mockFn).toBeCalledTimes(4);
|
||||
await wait(200);
|
||||
expect(pageChange).not.toBeCalled();
|
||||
});
|
@ -117,7 +117,11 @@ test('Renderer:Pagination with simple mode', async () => {
|
||||
expect(next).not.toHaveClass('is-disabled');
|
||||
|
||||
fireEvent.click(next);
|
||||
|
||||
await wait(500);
|
||||
expect(pageChange).toBeCalled();
|
||||
|
||||
await wait(200);
|
||||
expect(pageChange.mock.calls[0]).toEqual([3, 10]);
|
||||
|
||||
rerender(
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
FormBaseControl,
|
||||
buildApi,
|
||||
qsstringify,
|
||||
resolveEventData,
|
||||
autobind
|
||||
} from 'amis-core';
|
||||
import cx from 'classnames';
|
||||
@ -252,17 +253,24 @@ export default class RichTextControl extends React.Component<
|
||||
});
|
||||
}
|
||||
|
||||
handleChange(
|
||||
async handleChange(
|
||||
value: any,
|
||||
submitOnChange?: boolean,
|
||||
changeImmediately?: boolean
|
||||
) {
|
||||
const {onChange, disabled} = this.props;
|
||||
const {onChange, disabled, dispatchEvent} = this.props;
|
||||
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rendererEvent = await dispatchEvent(
|
||||
'change',
|
||||
resolveEventData(this.props, {value})
|
||||
);
|
||||
if (rendererEvent?.prevented) {
|
||||
return;
|
||||
}
|
||||
onChange?.(value, submitOnChange, changeImmediately);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user