如何使用 draft-js-mention-plugin 以编程方式添加提及?
How to programatically add mentions using draft-js-mention-plugin?
问题:
我正在尝试为使用 draft-js
+ draft-js-mention-plugin
创建的内容创建一个编辑界面。但是,editorState
没有持久化,只有纯文本。提及被保存为对象数组。现在我需要用这些数据重新创建 editorState。
示例:
我有这样的纯文本:
const content = '@marcello we need to add spell check'
还有一个 mentions
数组,其中包含这样的对象:
const mentions = [{
length: 8,
offset: 0,
user: 'user:59441f5c37b1e209c300547d',
}]
要使用纯文本创建 editorState,我使用了这些行:
const contentState = ContentState.createFromText(content)
EditorState.createWithContent(contentState)
效果很好。纯文本设置为初始状态,但没有提及。
现在我需要一种方法来添加基于 mentions
个对象的提及。
我正在尝试阅读库代码来弄清楚,但到目前为止没有成功。
我如何 "hacked" 我的解决方案:
// Imports
import { EditorState,convertToRaw, ContentState, convertFromRaw, genKey, ContentBlock } from 'draft-js';
// Init some kind of block with a mention
let exampleState = {
blocks: [
{
key: genKey(), //Use the genKey function from draft
text: 'Some text with mention',
type: 'unstyled',
inlineStyleRanges: [],
data: {},
depth: 0,
entityRanges: [
{ offset: 15, length: 7, key: 0 }
]
}
],
entityMap: [
"0": {
"type": "mention",
"mutability": "SEGMENTED",
"data": {
"mention": {
"name": "<name>",
"link": "<link>",
"avatar": "<avatar-url>"
}
}
}
]
};
this.state.editorState = EditorState.createWithContent(convertFromRaw(exampleState));
在这里你可以创建一些函数来输入你的文本并输出一个entityRange return a offset/length 并用你突出显示的东西替换"entityRanges"数组!
在这个例子中,单词 "mention" 会随着您使用提及插件的任何样式突出显示
旁注:
您可以使用草稿中的 ContentBlock class 或创建您自己的实现以使其更漂亮
这是我设法添加提及 (#)(使用 entityMap,到状态末尾的新块)的解决方案。它可以作为提及被检索等等......
当然可以简化,但它对我来说符合预期。
// import {....} from 'draft-js';
import Immutable, {List, Repeat} from 'immutable' ;
const addMentionLast = (editorState, mentionData) => {
if(!mentionData.id) return;
// debugger;
const contentState = editorState.getCurrentContent();
const oldBlockMap = contentState.getBlockMap();
const lastKey = lastNonEmptyKey(contentState);
const charData = CharacterMetadata.create();
//new state with mention
const selection = editorState.getSelection();
const entityKey = Entity.create('#mention', 'SEGMENTED', {"mention":{...mentionData }} );
//add text
const textWithEntity = Modifier.insertText(contentState, selection , `#${mentionData.name}` , null, entityKey);
const _editorState = EditorState.push(editorState, textWithEntity , 'insert-characters');
//create new block
const _newBlock = new ContentBlock({
key: genKey(),
type: 'unstyled',
depth: 0,
text: mentionData.name,
characterList: List(Repeat(charData, mentionData.name.length)),
});
//set the entity
const __newBlock = applyEntityToContentBlock(_newBlock,0, mentionData.name.length, entityKey)
//set new block in order..
const blocksMap =
Immutable.OrderedMap().withMutations(map => {
if (lastKey) {
//after the last non empty:
for (let [k, v] of oldBlockMap.entries()) {
map.set(k, v);
if (lastKey === k) {
map.set(k, v);
map.set(__newBlock.key, __newBlock);
}
}
}
else {
// first line:
map.set(__newBlock.key, __newBlock);
}
});
return EditorState.push(
_editorState,
ContentState
.createFromBlockArray(Array.from(blocksMap.values()))
.set('selectionBefore', contentState.getSelectionBefore())
.set('selectionAfter', contentState.getSelectionAfter())
)
}
function lastNonEmptyKey (content){
const lastNonEmpty = content.getBlockMap().reverse().skipUntil((block, _) => block.getLength()).first();
if (lastNonEmpty) return lastNonEmpty.getKey();
}
感谢大家的分享!
使用 "draft-js": "^0.11.6"
和 "draft-js-mention-plugin": "^3.1.5"
你可以做到
const stateWithEntity = editorState.getCurrentContent().createEntity(
'mention',
'IMMUTABLE',
{
mention: {id: 'foobar', name: 'foobar', link: 'https://www.facebook.com/foobar'},
},
)
const entityKey = stateWithEntity.getLastCreatedEntityKey()
const stateWithText = Modifier.insertText(stateWithEntity, editorState.getSelection(), 'foobar', null, entityKey)
EditorState.push(editorState, stateWithText)
您可能会发现此 https://github.com/draft-js-plugins/draft-js-plugins/issues/915#issuecomment-386579249 and https://github.com/draft-js-plugins/draft-js-plugins/issues/983#issuecomment-382150332 有帮助
问题:
我正在尝试为使用 draft-js
+ draft-js-mention-plugin
创建的内容创建一个编辑界面。但是,editorState
没有持久化,只有纯文本。提及被保存为对象数组。现在我需要用这些数据重新创建 editorState。
示例:
我有这样的纯文本:
const content = '@marcello we need to add spell check'
还有一个 mentions
数组,其中包含这样的对象:
const mentions = [{
length: 8,
offset: 0,
user: 'user:59441f5c37b1e209c300547d',
}]
要使用纯文本创建 editorState,我使用了这些行:
const contentState = ContentState.createFromText(content)
EditorState.createWithContent(contentState)
效果很好。纯文本设置为初始状态,但没有提及。
现在我需要一种方法来添加基于 mentions
个对象的提及。
我正在尝试阅读库代码来弄清楚,但到目前为止没有成功。
我如何 "hacked" 我的解决方案:
// Imports
import { EditorState,convertToRaw, ContentState, convertFromRaw, genKey, ContentBlock } from 'draft-js';
// Init some kind of block with a mention
let exampleState = {
blocks: [
{
key: genKey(), //Use the genKey function from draft
text: 'Some text with mention',
type: 'unstyled',
inlineStyleRanges: [],
data: {},
depth: 0,
entityRanges: [
{ offset: 15, length: 7, key: 0 }
]
}
],
entityMap: [
"0": {
"type": "mention",
"mutability": "SEGMENTED",
"data": {
"mention": {
"name": "<name>",
"link": "<link>",
"avatar": "<avatar-url>"
}
}
}
]
};
this.state.editorState = EditorState.createWithContent(convertFromRaw(exampleState));
在这里你可以创建一些函数来输入你的文本并输出一个entityRange return a offset/length 并用你突出显示的东西替换"entityRanges"数组!
在这个例子中,单词 "mention" 会随着您使用提及插件的任何样式突出显示
旁注:
您可以使用草稿中的 ContentBlock class 或创建您自己的实现以使其更漂亮
这是我设法添加提及 (#)(使用 entityMap,到状态末尾的新块)的解决方案。它可以作为提及被检索等等...... 当然可以简化,但它对我来说符合预期。
// import {....} from 'draft-js';
import Immutable, {List, Repeat} from 'immutable' ;
const addMentionLast = (editorState, mentionData) => {
if(!mentionData.id) return;
// debugger;
const contentState = editorState.getCurrentContent();
const oldBlockMap = contentState.getBlockMap();
const lastKey = lastNonEmptyKey(contentState);
const charData = CharacterMetadata.create();
//new state with mention
const selection = editorState.getSelection();
const entityKey = Entity.create('#mention', 'SEGMENTED', {"mention":{...mentionData }} );
//add text
const textWithEntity = Modifier.insertText(contentState, selection , `#${mentionData.name}` , null, entityKey);
const _editorState = EditorState.push(editorState, textWithEntity , 'insert-characters');
//create new block
const _newBlock = new ContentBlock({
key: genKey(),
type: 'unstyled',
depth: 0,
text: mentionData.name,
characterList: List(Repeat(charData, mentionData.name.length)),
});
//set the entity
const __newBlock = applyEntityToContentBlock(_newBlock,0, mentionData.name.length, entityKey)
//set new block in order..
const blocksMap =
Immutable.OrderedMap().withMutations(map => {
if (lastKey) {
//after the last non empty:
for (let [k, v] of oldBlockMap.entries()) {
map.set(k, v);
if (lastKey === k) {
map.set(k, v);
map.set(__newBlock.key, __newBlock);
}
}
}
else {
// first line:
map.set(__newBlock.key, __newBlock);
}
});
return EditorState.push(
_editorState,
ContentState
.createFromBlockArray(Array.from(blocksMap.values()))
.set('selectionBefore', contentState.getSelectionBefore())
.set('selectionAfter', contentState.getSelectionAfter())
)
}
function lastNonEmptyKey (content){
const lastNonEmpty = content.getBlockMap().reverse().skipUntil((block, _) => block.getLength()).first();
if (lastNonEmpty) return lastNonEmpty.getKey();
}
感谢大家的分享!
使用 "draft-js": "^0.11.6"
和 "draft-js-mention-plugin": "^3.1.5"
你可以做到
const stateWithEntity = editorState.getCurrentContent().createEntity(
'mention',
'IMMUTABLE',
{
mention: {id: 'foobar', name: 'foobar', link: 'https://www.facebook.com/foobar'},
},
)
const entityKey = stateWithEntity.getLastCreatedEntityKey()
const stateWithText = Modifier.insertText(stateWithEntity, editorState.getSelection(), 'foobar', null, entityKey)
EditorState.push(editorState, stateWithText)
您可能会发现此 https://github.com/draft-js-plugins/draft-js-plugins/issues/915#issuecomment-386579249 and https://github.com/draft-js-plugins/draft-js-plugins/issues/983#issuecomment-382150332 有帮助