我是 lexcal 的新手,我正在开发用于语音到文本的注释工具。
我用过 draftjs。我使用实体和装饰器来存储和管理每个单词的元数据。每个单词都是实体,每个实体都有时间戳作为元数据。
例子:我有一只猫
“我”、“有”、“一个”、“猫”是实体。
猫的实体数据是这样的
offset: 12,
length: 5,
data: {
original_word: 'cat',
start: 4.2,
end: 4,6,
}
所以当用户选择一个单词并将单词 cat 修改为 kitten 时,我仍然可以获得开始和结束时间戳。
你认为我可以用词法开发类似的东西吗?
当用户一次删除多个单词时,元数据中断是可以的……不需要完美,因为我迟早需要从 draftjs 迁移到某个编辑器库……
提前致谢。
最佳答案
方法:
- 监控词法更新
- 扩展 LexicalTextNode 的(实体)节点
- LexicalTextNode 之上的包装器节点(如 Comments)
监控词法更新
如果我正确理解你的问题,那是首选方法。
editor.registerUpdateListener(({editorState, previousEditorState, dirtyLeaves, dirtyNodes}) => {
// You can diff editor state and each of the individual nodes that
// were modified (dirtyLeaves and dirtyNodes)
});
请注意,一个 TextNode 可能包含多个单词。
权衡:
(+) 很整洁。它适用于现有的词法节点,并且不会修改渲染的 DOM。
(-) 差异节点可能很复杂。
扩展 LexicalTextNode 的(实体)节点
就像 MentionNode 一样,您可以拥有一个拥有自己数据的实体节点。
class MarkedNode extends TextNode {
__timestamps: {...};
setTimestamps() { this.getWritable().__timestamps = ... }
getTimestamps() { return this.__timestamps; }
}
权衡:
(+) 用标记节点替换每个单词很容易。
(-) 用您自己的自定义节点替换 TextNode 会终止围绕 TextNode 的所有优化,这些优化当前是协调器的一部分(合并相邻的文本节点)。拥有多个单独的 span 也会导致可访问性问题或其他外部插件(如 Grammarly)行为不当,并且还会降低其他依赖 TextNode 的插件的功效。
LexicalTextNode 之上的包装器节点(如 Comments)
就像以前的方法一样,但不是替换 TextNode,而是在顶部创建自己的包装器(元素)节点。鉴于基于字符的差异比较复杂且缓慢,这就是我们为 CommentPlugin 所采用的方法。 .
权衡:
(+) 添加自定义包装器节点很容易。
(-) 它仍然会对应用程序的整体性能产生负面影响。总的来说,它比以前的方法更好,因为您没有重写 TextNode 但也有大部分缺点。
TextNode 标记呢?
首先,一个TextNode可以包含多个单词。 TextNode 上的标记可能引用 1 个以上的单词。
除此之外,在 TextNode 上允许任意元数据意味着以后很难进行优化。例如,在合并节点时,我们查看它们的属性,并且仅在它们共享所有属性(模式、细节、样式等)时才合并它们。为了保持这种优化,我们必须建立规则来确定是否确实可以合并两个 TextNodes 节点。
关于draftjs - 我们可以在每个单词上存储元数据,让用户修改它并仍然保留它吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72283050/