首页 文章

如何在我的react组件中渲染draft js的LINK类型的实体映射?

提问于
浏览
2

我在我的redux商店中有这些数据,我想在反应组件中渲染 .

{
"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":{}
       }
   ]
}

我成功地设法创建了一个带草稿编辑器的链接类型,并且能够将其存储在数据库中,并且在呈现它时,除了链接之外我得到了整个文本 . 我在我的redux中有这个链接信息,即“实体图”以及“块”内的“entityRanges”,它告诉链接开始的偏移量和长度是多少 . 例如,在我的情况下,它是“这是链接”中的“链接” .

这是我用来从我的redux渲染上面的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 回答

  • 3

    你应该这样指定draft.js decorator

    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>
    

相关问题