Как отобразить карту сущностей типа LINK draft js в моем реактивном компоненте?
У меня есть эти данные в моем хранилище редуксов, которые я хочу отобразить в моем компоненте реакции.
{
"entityMap":{
"0":{
"type":"LINK",
"mutability":"MUTABLE",
"data":{"url":"www.google.co.in"}
}
},
"blocks":[
{
"key":"9k5h7",
"text":"this is the link",
"type":"unstyled",
"depth":0,
"inlineStyleRanges":[],
"entityRanges":[
{
"offset":12,
"length":4,
"key":0
}
],
"data":{}
}
]
}
Мне удалось создать тип ссылки с помощью чернового редактора, и я смог сохранить его в базе данных, и при рендеринге я получаю весь текст, кроме ссылки. У меня есть эта информация о ссылке в моем редуксе, т. Е. "Карта сущностей", а также "entityRanges" внутри "блоков", который сообщает, с какого смещения начинается ссылка и какова длина. Например, здесь, в моем случае, это "ссылка" в "это ссылка".
Вот код, который я использовал для рендеринга вышеупомянутого JSON из моего редукса:
render(){
return(
<div>
{
var nn = abovejsonfromreduxstore;
var editorState = EditorState.createWithContent(convertFromRaw(JSON.parse(nn)));
return (
<div>
<pre>
<Editor
editorState={editorState}
readOnly
/>
</pre>
</div>
</div>
}
</div>
);
}
Как изменить этот метод рендеринга, чтобы он также рендерил объект ссылки?
1 ответ
Вы должны указать декоратор draft.js следующим образом:
const decorator = new CompositeDecorator([
{
strategy: findLinkEntities,
component: Link,
},
]);
Пройти findLinkEntities
функция к strategy
собственность и Link
реагировать на компонент component
имущество:
function findLinkEntities(contentBlock, callback, contentState) {
contentBlock.findEntityRanges(
(character) => {
const entityKey = character.getEntity();
return (
entityKey !== null &&
contentState.getEntity(entityKey).getType() === 'LINK'
);
},
callback
);
}
const Link = (props) => {
const {url} = props.contentState.getEntity(props.entityKey).getData();
return (
<a href={url}>
{props.children}
</a>
);
};
После этого передайте этот декоратор createWithContent
метод:
this.state = {
editorState: EditorState.createWithContent(convertFromRaw(initialStateRaw), decorator)
};
Проверьте рабочий пример в скрытом фрагменте ниже:
const {Editor, CompositeDecorator, convertFromRaw, EditorState} = Draft;
const initialStateRaw = {
"entityMap":{
"0":{
"type":"LINK",
"mutability":"MUTABLE",
"data":{"url":"www.google.co.in"}
}
},
"blocks":[
{
"key":"9k5h7",
"text":"this is the link",
"type":"unstyled",
"depth":0,
"inlineStyleRanges":[],
"entityRanges":[
{
"offset":12,
"length":4,
"key":0
}
],
"data":{}
}
]
};
function findLinkEntities(contentBlock, callback, contentState) {
contentBlock.findEntityRanges(
(character) => {
const entityKey = character.getEntity();
return (
entityKey !== null &&
contentState.getEntity(entityKey).getType() === 'LINK'
);
},
callback
);
}
const Link = (props) => {
const {url} = props.contentState.getEntity(props.entityKey).getData();
return (
<a href={url}>
{props.children}
</a>
);
};
class Container extends React.Component {
constructor(props) {
super(props);
const decorator = new CompositeDecorator([
{
strategy: findLinkEntities,
component: Link,
},
]);
this.state = {
editorState: EditorState.createWithContent(convertFromRaw(initialStateRaw), decorator)
};
}
_handleChange = (editorState) => {
this.setState({ editorState });
}
render() {
return (
<div className="container-root">
<Editor
placeholder="Type away :)"
editorState={this.state.editorState}
onChange={this._handleChange}
/>
</div>
);
}
}
ReactDOM.render(<Container />, document.getElementById('react-root'))
body {
font-family: Helvetica, sans-serif;
}
.container-root {
border: 1px solid black;
padding: 5px;
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/draft-js/0.7.0/Draft.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/draft-js/0.10.0/Draft.js"></script>
<div id="react-root"></div>