chore: InputRichText组件配置支持同步更新 (#8608)

* fix: rich-text组件配置更新时,对应富文本编辑器也更新配置

* fix: rich-text组件配置更新时,对应富文本编辑器也更新配置

* fix: rich-text组件配置更新时,对应富文本编辑器也更新配置

* fix: rich-text组件配置更新时,对应富文本编辑器也更新配置
This commit is contained in:
sqzhou 2023-11-16 17:04:57 +08:00 committed by GitHub
parent 58a66fbdf7
commit e576aa588d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 35 deletions

View File

@ -92,11 +92,17 @@ class FroalaEditorComponent extends React.Component<FroalaEditorComponentProps>
this.destroyEditor();
}
componentDidUpdate() {
componentDidUpdate(prevProps: Readonly<FroalaEditorComponentProps>) {
if (this.props.config !== prevProps.config) {
this.editor?.destroy();
this.config = this.clone(this.props.config || this.config);
this.config = {...this.config};
this.editor = new FroalaEditor(this.element, this.config);
}
if (JSON.stringify(this.oldModel) == JSON.stringify(this.props.model)) {
return;
}
this.setContent();
}

View File

@ -41,7 +41,7 @@ import 'tinymce/plugins/help/js/i18n/keynav/zh_CN';
import 'tinymce/plugins/help/js/i18n/keynav/en';
import 'tinymce/plugins/help/js/i18n/keynav/de';
import {LocaleProps} from 'amis-core';
import {LocaleProps, autobind} from 'amis-core';
interface TinymceEditorProps extends LocaleProps {
model: string;
@ -69,7 +69,33 @@ export default class TinymceEditor extends React.Component<TinymceEditorProps> {
elementRef: React.RefObject<HTMLTextAreaElement> = React.createRef();
async componentDidMount() {
componentDidMount() {
this.initTiny();
}
componentDidUpdate(prevProps: TinymceEditorProps) {
const props = this.props;
if (
props.model !== prevProps.model &&
props.model !== this.currentContent
) {
this.editorInitialized && this.editor?.setContent(props.model || '');
}
if (this.props.config !== prevProps.config) {
tinymce.remove(this.editor);
this.initTiny();
}
}
componentWillUnmount() {
tinymce.remove(this.editor);
this.unmounted = true;
}
@autobind
async initTiny() {
const locale = this.props.locale;
const {onLoaded, ...rest} = this.props.config || {};
@ -167,22 +193,6 @@ export default class TinymceEditor extends React.Component<TinymceEditorProps> {
this.unmounted || tinymce.init(this.config);
}
componentDidUpdate(prevProps: TinymceEditorProps) {
const props = this.props;
if (
props.model !== prevProps.model &&
props.model !== this.currentContent
) {
this.editorInitialized && this.editor?.setContent(props.model || '');
}
}
componentWillUnmount() {
tinymce.remove(this.editor);
this.unmounted = true;
}
initEditor(e: any, editor: any) {
const {model, onModelChange, outputFormat, onFocus, onBlur} = this.props;

View File

@ -2,7 +2,6 @@ import React from 'react';
import {
FormItem,
FormControlProps,
FormBaseControl,
buildApi,
qsstringify,
resolveEventData,
@ -10,9 +9,8 @@ import {
} from 'amis-core';
import cx from 'classnames';
import {LazyComponent} from 'amis-core';
import {tokenize} from 'amis-core';
import {normalizeApi} from 'amis-core';
import {ucFirst} from 'amis-core';
import {ucFirst, anyChanged} from 'amis-core';
import type {FormBaseControlSchema, SchemaApi} from '../../Schema';
/**
@ -105,17 +103,50 @@ export default class RichTextControl extends React.Component<
};
state = {
config: null,
focused: false
};
config: any = null;
constructor(props: RichTextProps) {
super(props);
const finnalVendor =
props.vendor || (props.env.richTextToken ? 'froala' : 'tinymce');
this.handleFocus = this.handleFocus.bind(this);
this.handleBlur = this.handleBlur.bind(this);
this.handleChange = this.handleChange.bind(this);
this.state.config = this.getConfig(props);
}
componentDidUpdate(prevProps: Readonly<RichTextProps>) {
const props = this.props;
const finnalVendor =
props.vendor || (props.env.richTextToken ? 'froala' : 'tinymce');
if (finnalVendor === 'froala') {
if (
anyChanged(
['options', 'editorClass', 'placeholder', 'buttons'],
prevProps,
props
)
) {
this.setState({
config: this.getConfig(props)
});
}
} else if (finnalVendor === 'tinymce') {
if (anyChanged(['options', 'fileField'], prevProps, props)) {
this.setState({
config: this.getConfig(props)
});
}
}
}
getConfig(props: RichTextProps) {
const finnalVendor =
props.vendor || (props.env.richTextToken ? 'froala' : 'tinymce');
const imageReceiver = normalizeApi(
props.receiver,
props.receiver?.method || 'post'
@ -133,7 +164,7 @@ export default class RichTextControl extends React.Component<
const videoApi = buildApi(videoReceiver, props.data, {
method: props.videoReceiver.method || 'post'
});
this.config = {
return {
imageAllowedTypes: ['jpeg', 'jpg', 'png', 'gif'],
imageDefaultAlign: 'left',
imageEditButtons: props.imageEditable
@ -174,15 +205,12 @@ export default class RichTextControl extends React.Component<
blur: this.handleBlur
},
language:
!this.props.locale || this.props.locale === 'zh-CN' ? 'zh_cn' : ''
!this.props.locale || this.props.locale === 'zh-CN' ? 'zh_cn' : '',
...(props.buttons ? {toolbarButtons: props.buttons} : {})
};
if (props.buttons) {
this.config.toolbarButtons = props.buttons;
}
} else {
const fetcher = props.env.fetcher;
this.config = {
return {
...props.options,
onLoaded: this.handleTinyMceLoaded,
images_upload_handler: (blobInfo: any, progress: any) =>
@ -335,7 +363,7 @@ export default class RichTextControl extends React.Component<
onModelChange={this.handleChange}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
config={this.config}
config={this.state.config}
disabled={disabled}
locale={locale}
translate={translate}
@ -347,6 +375,7 @@ export default class RichTextControl extends React.Component<
@FormItem({
type: 'input-rich-text',
sizeMutable: false
sizeMutable: false,
detectProps: ['options', 'buttons']
})
export class RichTextControlRenderer extends RichTextControl {}