4.Draftjs 学习笔记-Decorators
来源:互联网 发布:1980西安坐标系数据 编辑:程序博客网 时间:2024/05/16 02:59
本节重点就是策略与渲染组件
Inline and block styles aren’t the only kind of rich styling that we might want to add to our editor. The Facebook comment input, for example, provides blue background highlights for mentions and hashtags.
除了内联与块样式,还有更多丰富的需求,比如评论里面的提及@
To support flexibility for custom rich text, Draft provides a “decorator” system. The tweet example offers a live example of decorators in action.
为了实现自定义富文本的灵活性,Draft 提供了一种“装饰器”系统。
CompositeDecorator | 复合装饰器
The decorator concept is based on scanning the contents of a given ContentBlock for ranges of text that match a defined strategy, then rendering them with a specified React component.
装饰器的原理,先根据策略(strategy)扫描内容块(ContentBlock),然后使用指定的组件渲染。
You can use the
CompositeDecorator
class to define your desired decorator behavior. This class allows you to supply multiple DraftDecorator objects, and will search through a block of text with each strategy in turn.
你可以使用CompositeDecorator
类定义装饰器行为。这个类允许使用多个装饰器对象,依次使用这些策略搜索内容块。
Decorators are stored within the
EditorState
record. When creating a new EditorState object, e.g. viaEditorState.createEmpty()
, a decorator may optionally be provided.
装饰器存储在EditorState
内。当使用EditorState.createEmpty()
,实例化一个EditorState对象,装饰器可以作为初始化参数。
Under the hood | 高级选项
When contents change in a Draft editor, the resultingEditorState
object will evaluate the newContentState
with its decorator, and identify ranges to be decorated. A complete tree of blocks, decorators, and inline styles is formed at this time, and serves as the basis for our rendered output.
In this way, we always ensure that as contents change, rendered decorations are in sync with ourEditorState
.
大意就是装饰器是随内容编辑同步执行装饰的
In the “Tweet” editor example, for instance, we use a CompositeDecorator that searches for @-handle strings as well as hashtag strings:
以tweet 为例就是搜索@ 字符串和 # hash标签
const compositeDecorator = new CompositeDecorator([ { strategy: handleStrategy, component: HandleSpan, }, { strategy: hashtagStrategy, component: HashtagSpan, },]);
This composite decorator will first scan a given block of text for @-handle matches, then for hashtag matches.
首先执行@ 匹配策略,然后是标签匹配
// Note: these aren't very good regexes, don't use them!const HANDLE_REGEX = /\@[\w]+/g;const HASHTAG_REGEX = /\#[\w\u0590-\u05ff]+/g;function handleStrategy(contentBlock, callback) { findWithRegex(HANDLE_REGEX, contentBlock, callback);}function hashtagStrategy(contentBlock, callback) { findWithRegex(HASHTAG_REGEX, contentBlock, callback);}function findWithRegex(regex, contentBlock, callback) { const text = contentBlock.getText(); let matchArr, start; while ((matchArr = regex.exec(text)) !== null) { start = matchArr.index; callback(start, start + matchArr[0].length); }}
The strategy functions execute the provided callback with the start and end values of the matching range of text.
策略函数的回调函数有匹配区域的起始值。
Decorator Components | 装饰组件
For your decorated ranges of text, you must define a React component to use to render them. These tend to be simple span elements with CSS classes or styles applied to them.
对于所要修饰的文本区域,必须定义一个组件渲染它们。通常是简单的带有css 类span来包裹。
In our current example, the CompositeDecorator object names HandleSpan and HashtagSpan as the components to use for decoration. These are just basic stateless components:
下面就是个复合装饰对象使用的无状态组件声明方式定义组件的实例
const HandleSpan = (props) => { return <span {...props} style={styles.handle}>{props.children}</span>;};const HashtagSpan = (props) => { return <span {...props} style={styles.hashtag}>{props.children}</span>;};Note
that
props.children
is passed through to the rendered output. This is done to ensure that the text is rendered within the decorated span.
props.children
确保渲染内容是所要装饰的范围内
You can use the same approach for links, as demonstrated in our link example.
参考上一篇中的代码实例
Beyond CompositeDecorator| 不局限于CompositeDecorator
The decorator object supplied to an
EditorState
need only match the expectations of theDraftDecoratorType
Flow type definition, which means that you can create any decorator classes you wish, as long as they match the expected type – you are not bound byCompositeDecorator
.
装饰器只要符合DraftDecoratorType
的类型定义,就可以创建任意类型的装饰器而不必使用CompositeDecorator
包裹。
Setting new decorators| 动态修改decorators
Further, it is acceptable to set a new decorator value on the EditorState on the fly, during normal state propagation – through immutable means, of course.
进一步讲,在一般state
传递过程中可以设置EditorState中新的decorator,当然使用的immutable
方式。
This means that during your app workflow, if your decorator becomes invalid or requires a modification, you can create a new decorator object (or use null to remove all decorations) and
EditorState.set()
to make use of the new decorator setting.
这意味着,在应用流程中,当之前的decorator不能用了,或需要更改时,你可以创建个新的(或使用null去除所有装饰器),通过EditorState.set()
生效
For example, if for some reason we wished to disable the creation of @-handle decorations while the user interacts with the editor, it would be fine to do the following:
例如,当用户交互时我们去除@装饰器效果,代码如下:
function turnOffHandleDecorations(editorState) { const onlyHashtags = new CompositeDecorator([{ strategy: hashtagStrategy, component: HashtagSpan, }]); return EditorState.set(editorState, {decorator: onlyHashtags});}
The
ContentState
for thiseditorState
will be re-evaluated with the new decorator, and @-handle decorations will no longer be present in the next render pass.
editorState
中的ContentState
将使用新的装饰器重新渲染,@-handle装饰效果在下次渲染中实效。
Again, this remains memory-efficient due to data persistence across immutable objects.
还有就是因为是immutable
所以内存还是很高效。
动手实践
代码以上篇为例,系列结束时,样例托管在github上。
- 4.Draftjs 学习笔记-Decorators
- 1.Draftjs 学习笔记
- 3.Draftjs 学习笔记-Entities
- 7.Draftjs 学习笔记-StateToHtml
- 2.Draftjs 学习笔记-Rich Styling
- TypeScript 学习笔记10: Decorators
- 5.Draftjs 学习笔记-自定义控件(多媒体)
- decorators.xml学习
- python decorators
- decorators.xml
- decorators.xml
- Python Decorators
- decorators.xml
- Decorators详解
- decorators.xml
- decorators.xml
- [Python]Decorators
- decorators.xml
- Unity 游戏框架搭建 (四) 简易有限状态机
- 游戏中几种概率设计
- YOLO源码详解(五)- YOLO中的7*7个grid和RPN中的9个anchors
- HDU3667 Transportation(spfa费用流+拆边)
- Android进阶——多线程系列之四大线程池的使用介绍
- 4.Draftjs 学习笔记-Decorators
- [GI系列]0.0-下一阶段博文说明
- Mybatis中使用Association元素进行一对一级联查询
- Unity 游戏框架搭建 (五) 简易消息机制
- ss按时发翁二无热若无
- SRAM和SDRAM的区别
- List数组排序
- 国内成品油价格将迎“两连涨” 或刷新年内最高涨幅
- Unity 游戏框架搭建 (六) 关于框架的一些好文和一些思考