Как отобразить карту сущностей типа 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>

Другие вопросы по тегам