继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Draft 文档翻译 - 高级主题 - Decorators

路北
关注TA
已关注
手记 36
粉丝 90
获赞 327
Decorators

内联样式和块级样式都不是只是我们想要添加到编辑富中的富内容。例如,Facebook评论输入提供了蓝色背景亮点,用于提及和标签。

为了支持自定义富文本的灵活性,草稿提供了一个“装饰器”系统。推特示例提供了一个现实的装饰器的例子。

(“装饰器是用来添加高级富内容的一种方法”)

CompositeDecorator
  1. 扫描给定的内容块
  2. 满足定义的匹配策略的文本范围。
  3. 使用自定义的React组件去呈现他们。

可以使用CompositeDecorator类定义所需的装饰器行为。此类允许您提供多个DraftDecorator对象,并依次搜索每个策略的一组文本。

装饰器存储在EditorState记录中。当创建一个新的EditorState对象,例如 通过EditorState.createEmpty(),可以选择提供装饰器。

基于钩子

当Draft编辑器中的内容更改时,生成的EditorState对象将使用其装饰器评估新的ContentState,
并标识要进行装饰的范围。 此时形成了一个完整的块,装饰器和内联样式,作为我们渲染输出的基础。

通过这种方式,我们始终保证随着内容的改变,渲染的装饰与我们的EditorState同步。

例如,在“Tweet”编辑器示例中,我们使用一个CompositeDecorator来搜索@ -handle字符串以及主题标签字符串:

const compositeDecorator = new ComponsiteDecorator([
    {
        strategy: handleStrategy,
        component: HandleSpan,
    },
    {
        strategy: hashtagStrategy,
        component: HashtagSpan,
    }
])

此复合装饰器将首先扫描给定的文本块以获取@-handle匹配,然后对于hashtag匹配进行扫描。

const HANDLE_REGEX = /\@[\W]+/g;
const HASHTAG_REGEX = /\#[\w\u0590-\u05ff]+/g;

function handleStrategy(contentBlock, callback, contentState){
    findWithRegex(HANDLE_REGEX, contentBlock, callback)
}

function hashtagStrategy(contentBlock, callback, contentState) {
    findWithRegex(HASHTAG_REGEX, contentBLCOK, callback);
}

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

策略函数执行提供的回调与匹配的文本范围的起始和结束值。

Decorator Components

对于您装饰的文本范围,您必须定义一个用于呈现它们的React组件。 这些往往是使用 CSS类 或 style 的简单 span 元素。

在我们当前的示例中,CompositeDecorator对象将HandleSpan和HashtagSpan命名为用于装饰的组件。
这些只是基本的无状态组件:

const HandleSpan = (props) => {
    return <span {...props} style={styles.handle}>{props.children}</span>
};

const HashtagSpan = (props) => {
  return <span {...props} style={styles.hashtag}>{props.children}</span>;
};

注意,props.children被传递到渲染的输出。 这样做是为了确保文本在装饰的范围内呈现。

您可以使用相同的方法进行链接,如我们的链接示例所示。

超越CompositeDecorator

提供给EditorState的装饰器对象只需要符合DraftDecoratorType Flow类型定义的期望,这意味着您可以创建任何您想要的装饰器类,只要它们与预期类型相匹配,则不受CompositeDecorator的限制。

设置新的装饰

此外,当然,在正常状态传播期间,通过不可变的方式,可以在EditorState上设置新的装饰器值。

这意味着在您的应用程序工作流程中,如果您的装饰器无效或需要修改,您可以创建一个新的装饰器对象(或使用null删除所有装饰)和EditorState.set()以使用新的装饰器设置。

例如,如果由于某种原因,我们希望在用户与编辑器交互时禁用@ -handle装饰的创建,那么执行以下操作会很好:

function turnOffHandleDecorations(editorState) {
  const onlyHashtags = new CompositeDecorator([{
    strategy: hashtagStrategy,
    component: HashtagSpan,
  }]);
  return EditorState.set(editorState, {decorator: onlyHashtags});
}

将使用新装饰器重新评估此editorState的ContentState,并且@ -handle装饰将不再存在于下一个渲染过程中。

同样,由于不可变对象上的数据持久性,这仍然是内存有效的。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP