DraftJS Entity 系统

2,765 阅读2分钟

Entity系统

DraftJS使用Entity来实现包含_metadata_的文本,比如链接Link、提及Mention和嵌入式内容Embedded Content**。

属性

一个_Entity_包含三个属性:

  • type 用来描述Entity的类型,如LINKMENTION等。
  • mutability 指示对象是否可改变,可能的值有三个:IMMUTABLEMUTABLE以及SEGMENTED。   IMMUTABLE 修改Entity的文本会删除整个Entity。   MUTABLE 允许自由改变Entity的文本。   SEGMENTEDIMMUTABLE大致相同,区别详见官方文档。   下面有一个例子来说明这三者区别: 编辑器中对一个链接进行操作,初始文本是:  其他文本,这是链接,其他文本               删除一个字     添加一个字           **IMMUTABLE**/**SEGMENTED**     其他文本,,其他文本     其他文本,这是个链接,其他文本           **MUTABLE**     其他文本,[这链接](#),其他文本     其他文本,[这是个链接](#),其他文本    
  • data 包含Entitymetadata

所有Entity都保存在ContentState中,通过一个entityKey来引用。

Editor内使用来**装饰器(Decorator自定义组件(Custom Block Component)**来装饰Entity

创建

创建Entity的API为:

contentState.createEntity(type, mutability, data)

返回值为包含该EntitycontentState,通过getLastCreatedEntityKey()函数来得到entityKey,用来引用该Entity

下面的例子是插入一个链接到编辑器中:

import { Modifier, EditorState } from 'draft-js';

function insertLink(editorState, link, title) {
  let contentState = editorState.getCurrentContent();
  const selection = editorState.getSelection();
  //创建Entity
  const contentStateWithEntity = contentState.createEntity('LINK', 'MUTABLE', {
    href: link
  });
  //获取entityKey
  const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
  if (title && title.length > 0) {
    //包含title,则替换选中部分
    contentState = Modifier.replaceText(
      contentState, 
      selection, 
      `${title}`,
      editorState.getCurrentInlineStyle(), 
      entityKey
    );
  } else {
    //给选中部分加上链接
    contentState = Modifier.applyEntity(contentState, selection, entityKey);
  }
  const newState = EditorState.push(editorState, contentState, 'insert-characters');
  return newState;
}

详细例子可以参看开源富文本编辑器shreditor

引用

使用entityKey来引用Entity

function getEntityData(editorState) {
  //获取选中block
  const block = getSelectBlock(editorState);
  const entityKey = block.getEntityAt(0);
  const contentState = editorState.getCurrentContent();
  const entity = entityKey ? contentState.getEntity(entityKey) : null;
  return entity ? entity.getData() : {};
}

如果引用上一步创建的Entity,则上面的方法返回的就是

{href: "xxx.xxx"}