0

目前我有一个这样的 DraftJS 编辑器:

<Editor
  editorState={this.state.editorState}
  handleKeyCommand={this.handleKeyCommand}
  onChange={this.onChange}
  placeholder="Write a tweet..."
  ref="editor"
  spellCheck={true}
/>

具有状态的构造函数:

constructor(props) {
  super(props);
  const compositeDecorator = new CompositeDecorator([{
    strategy: mentionStrategy,
    component: MentionSpan,
  }, {
    strategy: hashtagStrategy,
    component: HashtagSpan,
  }, {
    strategy: emojiStrategy,
    component: EmojiSpan,
  }]);

  this.state = {
    conversationActive: null,
    editorState: EditorState.createEmpty(compositeDecorator),
  };

  this.focus = () => this.refs.editor.focus();
  this.onChange = (editorState) => this.setState({editorState});
  this.logState = () => console.log(this.state.editorState.toJS());
  this.handleKeyCommand = () => 'not-handled';
}

我甚至制定了一个与一系列正则表达式匹配的装饰器策略,以确定一个块是否是一个表情符号,如:D, :(,:|等。

问题是我无法弄清楚如何将更多道具“传递给策略中的元素”或如何从匹配中创建实体......

这是策略:

const findWithRegex = (regex, contentBlock, callback) => {
  const text = contentBlock.getText();
  let matchArr, start;
  while ((matchArr = regex.exec(text)) !== null) {
    start = matchArr.index;
    callback(start, start + matchArr[0].length);
  }
}

const emojiRegexes = [...];

export const emojiStrategy = (contentBlock, callback, contentState) => {
  for (let i = 0; i < emojiRegexes.length; i++) {
    findWithRegex(emojiRegexes[i].regex, contentBlock, callback);
  }
}

export const EmojiSpan = (props) => {
  return (
    <span
      className={styles.emoji}
      data-offset-key={props.offsetKey}
    >
      {props.children}
    </span>
  );
};

谁能帮我?谢谢!

PS:我似乎无法从 Draft-js 中找到真正深入的文档,github 上的文档只有肤浅的描述和虚拟示例。

4

1 回答 1

0

设法以不同的方式做我想做的事,首先,用 unicode 字符替换文本,这些字符将来将是带有元数据的实体。代码如下:

onChange(editorState) {
  const contentState = editorState.getCurrentContent();
  let currentText = contentState.getBlockForKey(editorState.getSelection().getAnchorKey()).getText();

  for (let i = 0; i < emojiRegexes.length; i++) {
    currentText = currentText.replace(emojiRegexes[i].regex, () => emojiRegexes[i].unicode)
  }

  if (currentText === contentState.getBlockForKey(editorState.getSelection().getAnchorKey()).getText()) {
    this.setState({ editorState });
    return;
  }

  const updatedSelection = editorState.getSelection().merge({
    anchorOffset: 0,
  });

  const edited = EditorState.push(
    editorState,
    Modifier.replaceText(
      contentState,
      updatedSelection,
      currentText
    ),
    'change-block-data'
  );

  this.setState({ editorState: edited });
}
于 2017-02-23T21:27:39.743 回答