我试过使用componentWillMount和componentDidMount在React上下文中初始化CKEditor,但无论尝试哪种组合都似乎不起作用。除了切换编辑器之外,是否有人找到了解决方法?
我试过使用componentWillMount和componentDidMount在React上下文中初始化CKEditor,但无论尝试哪种组合都似乎不起作用。除了切换编辑器之外,是否有人找到了解决方法?
我在Npm上发布了一个包,用于在React中使用CKEditor。只需一行代码即可将其集成到您的项目中。
Github链接- https://github.com/codeslayer1/react-ckeditor.
如何使用?
npm install react-ckeditor-component --save
命令安装该包。<CKEditor activeClass="editor" content={this.state.content} onChange={this.updateContent} />
该包使用CKEditor的默认构建版本,但您也可以使用自定义构建版本以及您喜欢的任何插件。它还包括一个示例应用程序。希望您会发现它有用。
Sage在他的答案中描述了一个非常棒的解决方案。这对我来说救命了,因为我刚刚开始使用React,并且我需要它来实现我的需求。不过,我还是改变了实现方式,同时采纳了Jared的建议(使用componentDidMount
)。此外,我的需求是要有一个改变回调函数,像这样:
组件的使用:
<CKEditor value={this.props.value} onChange={this.onChange}/>
将此内容添加至index.html
:
<script src="//cdn.ckeditor.com/4.6.1/basic/ckeditor.js"></script>
使用以下组件代码:
import React, {Component} from "react";
export default class CKEditor extends Component {
constructor(props) {
super(props);
this.componentDidMount = this.componentDidMount.bind(this);
}
render() {
return (
<textarea name="editor" cols="100" rows="6" defaultValue={this.props.value}></textarea>
)
}
componentDidMount() {
let configuration = {
toolbar: "Basic"
};
CKEDITOR.replace("editor", configuration);
CKEDITOR.instances.editor.on('change', function () {
let data = CKEDITOR.instances.editor.getData();
this.props.onChange(data);
}.bind(this));
}
}
再次感谢 Sage!
以下是基本版本的改进版,支持在同一页面上使用多个 CKEditor 实例:
import React, {Component} from "react";
export default class CKEditor extends Component {
constructor(props) {
super(props);
this.elementName = "editor_" + this.props.id;
this.componentDidMount = this.componentDidMount.bind(this);
}
render() {
return (
<textarea name={this.elementName} defaultValue={this.props.value}></textarea>
)
}
componentDidMount() {
let configuration = {
toolbar: "Basic"
};
CKEDITOR.replace(this.elementName, configuration);
CKEDITOR.instances[this.elementName].on("change", function () {
let data = CKEDITOR.instances[this.elementName].getData();
this.props.onChange(data);
}.bind(this));
}
}
请注意,这还需要传递一些唯一的ID:<CKEditor id={...} value={this.props.value} onChange={this.onChange}/>
blur
" 更改为 "change
",因为 "blur
" 没有考虑在 CKEditor 中输入内容,然后立即提交表单(例如按钮点击)的情况。 - Sander Verhagenchange
"事件导致CKEditor变得缓慢时,我正在寻找一种像"change
"一样快速的解决方案。 - Reed G. Law这是一个用于显示P段落文本的React组件。如果用户想要编辑段落中的文本,他们可以单击它,这将会附加一个CKEditor实例。当用户完成在编辑器实例中更改文本后,“失焦”事件将触发,将CKEditor数据传输到状态属性并销毁CKEditor实例。
import React, {PropTypes, Component} from 'react';
export default class ConditionalWYSIWYG extends Component {
constructor(props) {
super(props);
this.state = {
field_name:this.props.field_name,
field_value:this.props.field_value,
showWYSIWYG:false
};
this.beginEdit = this.beginEdit.bind(this);
this.initEditor = this.initEditor.bind(this);
}
render() {
if ( this.state.showWYSIWYG ) {
var field = this.state.field_name;
this.initEditor(field);
return (
<textarea name='editor' cols="100" rows="6" defaultValue={unescape(this.state.field_value)}></textarea>
)
} else {
return (
<p className='description_field' onClick={this.beginEdit}>{unescape(this.state.field_value)}</p>
)
}
}
beginEdit() {
this.setState({showWYSIWYG:true})
}
initEditor(field) {
var self = this;
function toggle() {
CKEDITOR.replace("editor", { toolbar: "Basic", width: 870, height: 150 });
CKEDITOR.instances.editor.on('blur', function() {
let data = CKEDITOR.instances.editor.getData();
self.setState({
field_value:escape(data),
showWYSIWYG:false
});
self.value = data;
CKEDITOR.instances.editor.destroy();
});
}
window.setTimeout(toggle, 100);
}
}
self.value = data
允许我通过简单的 ref 从父组件中检索文本。
window.setTimeout();
给 React 时间去执行它该做的事情。如果没有这个延迟,控制台会报出 Cannot read property 'getEditor' of undefined
的错误。
希望这能帮到您。
只需在index.html
中引用ckeditor.js
,并使用window.CKEDITOR
来使用它。不要像React组件文档中那样直接使用CKEDITOR
。
只需阅读ckeditor.js
的第一行,您就会发现关于CKEDITOR
定义的内容。
CKEDITOR.disableAutoInline = true
然后,对于实际组件...
import React, {Component} from 'react';
export default class CKEditor extends Component {
constructor(props) {
super(props);
this.elementName = "editor_" + this.props.id;
this.componentDidMount = this.componentDidMount.bind(this);
this.onInput = this.onInput.bind(this);
}
onInput(data) {
console.log('onInput: ' + data);
}
render() {
return (
<div
contentEditable={true}
suppressContentEditableWarning
className="rte"
id={this.elementName}>
{this.props.value}</div>
)
}
componentDidMount() {
let configuration = {
toolbar: "Basic"
};
CKEDITOR.inline(this.elementName, configuration);
CKEDITOR.instances[this.elementName].on("change", function() {
let data = CKEDITOR.instances[this.elementName].getData();
this.onInput(data);
}.bind(this));
}
}
使用方法大致如下:
<CKEditor id="102" value="something" onInput={this.onInput} />