【问题标题】:Draft.js: How to insert new block before atomicDraft.js:如何在原子之前插入新块
【发布时间】:2016-12-16 23:36:20
【问题描述】:

我想在块之后添加新行。我当前的功能是下一个:

   _insert_new_block(editorState) {
      const selection = editorState.getSelection();
      const newBlock = new ContentBlock({
         key: genKey(),
         type: 'unstyled',
         text: ' ',
         characterList: List()
      });
      const contentState = editorState.getCurrentContent();
      const new_block_map = contentState.getBlockMap().set(newBlock.key, newBlock);
      const newContentState = contentState.set('blockMap', new_block_map);
      const new_contentState = contentState.merge({
        blockMap: new_block_map,
        selectionBefore: selection.merge({
          anchorKey: newBlock.key,
          anchorOffset: 0,
          focusKey: newBlock.key,
          focusOffset: 0,
          isBackward: false
        }),
        selectionAfter: selection
      });
      return EditorState.push(
         editorState,
         new_contentState,
         'insert-fragment'
      );
   }

在我的内容末尾插入了新块,但是当我单击新创建块时出现此错误 -

getUpdatedSelectionState.js:38 Uncaught TypeError: Cannot read property 'get' of undefined

以及错误所在的文件

'use strict';

var DraftOffsetKey = __webpack_require__(331);

var nullthrows = __webpack_require__(305);

function getUpdatedSelectionState(editorState, anchorKey, anchorOffset, focusKey, focusOffset) {
  var selection = nullthrows(editorState.getSelection());
  if (process.env.NODE_ENV !== 'production') {
    if (!anchorKey || !focusKey) {
      /*eslint-disable no-console */
      console.warn('Invalid selection state.', arguments, editorState.toJS());
      /*eslint-enable no-console */
      return selection;
    }
  }

  var anchorPath = DraftOffsetKey.decode(anchorKey);
  var anchorBlockKey = anchorPath.blockKey;
  var anchorLeaf = editorState.getBlockTree(anchorBlockKey).getIn([anchorPath.decoratorKey, 'leaves', anchorPath.leafKey]);

  var focusPath = DraftOffsetKey.decode(focusKey);
  var focusBlockKey = focusPath.blockKey;
  var focusLeaf = editorState.getBlockTree(focusBlockKey).getIn([focusPath.decoratorKey, 'leaves', focusPath.leafKey]);

  var anchorLeafStart = anchorLeaf.get('start');
  var focusLeafStart = focusLeaf.get('start');

  var anchorBlockOffset = anchorLeaf ? anchorLeafStart + anchorOffset : null;
  var focusBlockOffset = focusLeaf ? focusLeafStart + focusOffset : null;

  var areEqual = selection.getAnchorKey() === anchorBlockKey && selection.getAnchorOffset() === anchorBlockOffset && selection.getFocusKey() === focusBlockKey && selection.getFocusOffset() === focusBlockOffset;

  if (areEqual) {
    return selection;
  }

  var isBackward = false;
  if (anchorBlockKey === focusBlockKey) {
    var anchorLeafEnd = anchorLeaf.get('end');
    var focusLeafEnd = focusLeaf.get('end');
    if (focusLeafStart === anchorLeafStart && focusLeafEnd === anchorLeafEnd) {
      isBackward = focusOffset < anchorOffset;
    } else {
      isBackward = focusLeafStart < anchorLeafStart;
    }
  } else {
    var startKey = editorState.getCurrentContent().getBlockMap().keySeq().skipUntil(function (v) {
      return v === anchorBlockKey || v === focusBlockKey;
    }).first();
    isBackward = startKey === focusBlockKey;
  }

  return selection.merge({
    anchorKey: anchorBlockKey,
    anchorOffset: anchorBlockOffset,
    focusKey: focusBlockKey,
    focusOffset: focusBlockOffset,
    isBackward: isBackward
  });
}

module.exports = getUpdatedSelectionState;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4)))

什么可能导致此错误以及如何正确执行插入?

【问题讨论】:

  • 请粘贴错误堆栈
  • 对不起。我更新了我的问题以包含代码

标签: reactjs draftjs


【解决方案1】:

这是一个插入新块的函数

export default (direction, editorState) => {
    const selection = editorState.getSelection();
    const contentState = editorState.getCurrentContent();
    const currentBlock = contentState.getBlockForKey(selection.getEndKey());

   const blockMap = contentState.getBlockMap()
   // Split the blocks
   const blocksBefore = blockMap.toSeq().takeUntil(function (v) {
      return v === currentBlock
   })
   const blocksAfter = blockMap.toSeq().skipUntil(function (v) {
      return v === currentBlock
   }).rest()
   const newBlockKey = genKey()
   let newBlocks = direction === 'before' ? [
      [newBlockKey, new ContentBlock({
         key: newBlockKey,
         type: 'unstyled',
         text: '',
         characterList: List(),
      })],
      [currentBlock.getKey(), currentBlock],
   ] : [
      [currentBlock.getKey(), currentBlock],
      [newBlockKey, new ContentBlock({
         key: newBlockKey,
         type: 'unstyled',
         text: '',
         characterList: List(),
      })],
   ];
   const newBlockMap = blocksBefore.concat(newBlocks, blocksAfter).toOrderedMap()
   const newContentState = contentState.merge({
      blockMap: newBlockMap,
      selectionBefore: selection,
      selectionAfter: selection,
   })
   return EditorState.push(editorState, newContentState, 'insert-fragment');
}

在任何地方你都可以像那样使用这个功能

var editorState = insert_block('before', editorState);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多