尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

fast-element NodeBehaviorOptions 接口详解:节点观察配置契约与 children/slotted 指令实现

fast-element NodeBehaviorOptions 接口详解:节点观察配置契约与 children/slotted 指令实现 前端UI组件【免费下载链接】fastThe adaptive interface system for modern web experiences.项目地址https://gitcode.com/gh_mirrors/fa/fast点击查看免费下载NodeBehaviorOptions是 microsoft/fast-element即当前仓库packages/fast-element包中用于配置节点观察行为的统一选项接口。它是children子节点观察与slotted插槽节点观察两大模板指令共享的配置契约理解它就能理解 fast-element 如何把 DOM 节点集合同步到视图模型属性。读完本文你将掌握该接口的完整签名、property与filter两个属性的语义与取值规则、ElementsFilter过滤函数的构造方法以及它在指令中的底层运行机制并能够直接在模板中使用。接口定义一次掌握签名与泛型在 fast-element 1.x API 文档 中NodeBehaviorOptions的原始签名如下export interface NodeBehaviorOptionsT any该接口的官方定义位于 node-observation.ts其 JSDoc 注释明确写着 Options for configuring node observation behavior用于配置节点观察行为的选项。结合文档与源码可以提炼出接口的完整结构/** * Options for configuring node observation behavior. * public */ export interface NodeBehaviorOptionsT any { /** 观察到的节点要赋值到的属性名 */ property: T; /** 过滤与属性同步的节点数组中的每个元素都会调用一次 */ filter?: ElementsFilter; }接口是泛型接口默认类型参数为any。类型参数T直接作用于property字段使得在强类型场景下可以把property约束为具体的键名类型。这一点从children/slotted工厂函数的声明可以得到印证childrenTSource any, TParent any(propertyOrOptions: (keyof TSource string) | ChildrenDirectiveOptionskeyof TSource string)当传入字符串形式时会被约束为源对象TSource的合法键名从而在编译期保证赋值的属性确实存在于视图模型上。property观察结果的赋值目标必填官方文档对property属性的描述为The property to assign the observed nodes to要向其赋观察节点集合的属性类型为T。属性页详见 fast-element.nodebehavioroptions.property。从源码看property是必填项且它的真正消费点在 node-observation.ts 的updateTarget方法中protected updateTarget(source: any, value: ReadonlyArrayany): void { source[this.options.property] value; }即每次节点集合发生变化时fast-element 会把计算好的节点数组直接写入source[property]——source正是当前视图模型view model。因此property应当指向视图模型上存在或计划存在的键若希望模板绑定如repeat、when能响应节点集合的变化通常应配合Observable.defineProperty将该属性声明为可观察属性observable否则节点更新后 DOM 不会自动重渲染一个有趣且重要的实现细节是filter的判定是filter in this.options见 computeNodes即只要选项中存在filter键就执行过滤与值是否为undefined无关。filter一次性回调式节点过滤可选官方文档对filter的描述为Filters nodes that are synced with the property. Called one time for each element in the array过滤与属性同步的节点对数组中的每个节点各调用一次类型为ElementsFilter且属性本身可选。属性页详见 fast-element.nodebehavioroptions.filter。这里的Called one time for each element in the array并非模板绑定语义而是标准的Array.prototype.filter回调语义fast-element 在computeNodes中直接调用nodes.filter(this.options.filter!)过滤函数会按数组顺序对每个节点执行一次返回true的节点保留、false的剔除。ElementsFilter 函数签名ElementsFilter是过滤器函数类型文档化签名为export declare type ElementsFilter (value: Node, index: number, array: Node[]) boolean;该类型同样定义在 node-observation.ts 中官方类型页见 fast-element.elementsfilter。需要说明的是文档化签名中index、array为必填参数而源码实现将其标为可选index?: number, array?: Node[]实际运行时它就是标准数组 filter 回调三个参数都会按序传入所以按哪种签名书写都不会出错。它的三个入参含义分别是参数含义value当前被检查的节点Nodeindex节点在数组中的索引array正在被过滤的节点数组elements() 过滤工厂函数绝大多数场景无需手写过滤函数fast-element 提供了开箱即用的elements()工厂node-observation.tsconst selectElements (value: Node): boolean value.nodeType 1; export const elements (selector?: string): ElementsFilter selector ? value value.nodeType 1 (value as HTMLElement).matches(selector) : selectElements;其行为规则清晰不传参数只保留nodeType 1的节点即仅选取元素节点Element剔除文本节点、注释节点等传入 CSS 选择器字符串在元素节点基础上进一步用Element.matches(selector)匹配只保留命中选择器的元素。也就是说elements(li)等价于只保留li元素elements()等价于只保留任意元素。谁在使用 NodeBehaviorOptionschildren 与 slotted 指令NodeBehaviorOptions不是孤立接口它是 fast-element 节点观察体系的地基。从源码结构看所有节点观察指令都建立在它之上NodeBehaviorOptionsT // 公共选项契约 ▲ ▲ ChildListDirectiveOptionsT SlottedDirectiveOptionsT SubtreeDirectiveOptionsT ▲ ChildrenDirectiveOptionsT对应关系如下children.tsChildListDirectiveOptions与SubtreeDirectiveOptions均extends NodeBehaviorOptions再合并为ChildrenDirectiveOptions供ChildrenDirective与children()工厂使用用于观察元素的childNodes或按选择器匹配的后代节点slotted.tsSlottedDirectiveOptions extends NodeBehaviorOptions供SlottedDirective与slotted()工厂使用用于观察HTMLSlotElement.assignedNodes()的分布结果。由此可见凡是需要把 DOM 节点集合同步到视图模型属性的功能最终都落到这两个选项字段上。底层运行机制从 bind 到 property 赋值的完整链路NodeBehaviorOptions的消费方是NodeObservationDirective抽象基类node-observation.ts其 JSDoc 注明Internally used by the SlottedDirective and the ChildrenDirective。整个生命周期可归纳为bind绑定bind()从视图控制器获取目标 DOM 节点先执行一次updateTarget(controller.source, this.computeNodes(target))完成初始赋值随后调用observe(target)开启观察computeNodes计算getNodes()取原始节点children用childNodes或querySelectorAll(selector)slotted用assignedNodes()若存在filter则执行nodes.filter(filter)observe观察ChildrenDirective通过MutationObserverchildList: true构造时强制写入监听子节点变化回调中再次执行computeNodes并updateTarget见 children.tsSlottedDirective通过监听slotchange事件实现同样的重算并赋值见 slotted.tsunbind解绑updateTarget(controller.source, emptyArray)先把属性置为空数组再disconnect()断开观察避免泄漏。两个观察策略各有适用场景children适合组件内部结构如导航菜单的子项、列表容器随自身 DOM 变化的情况slotted适合自定义元素通过slot接收外部内容light DOM并需要在插槽内容变化时做出反应的情况。实战用法两种配置形式children()与slotted()工厂函数都同时接受两种入参形式以children为例见 children.ts形式一仅传属性名字符串。工厂内部会将其展开为{ property: propertyOrOptions }import { html, children, Observable } from microsoft/fast-element; class MyNav extends HTMLElement { items: Element[] []; } Observable.defineProperty(MyNav.prototype, items); const template htmlMyNav div rolelist ${children(items)}/div ;形式二传完整选项对象。此时即可配置filter这正是NodeBehaviorOptions两个字段同时发挥作用的形式import { html, children, elements } from microsoft/fast-element; const template htmlMyNav div rolelist ${children({ property: items, filter: elements([rolelistitem]) })} /div ;slotted()用法对称import { html, slotted, elements } from microsoft/fast-element; const template htmlMyCard slot ${slotted({ property: content, filter: elements(p) })}/slot ;这里slotted只会把插槽分配的节点中p元素同步给content属性文本节点与其他元素会被过滤掉。需要提醒的是上述示例的赋值路径bind→updateTarget→source[property]由源码确认但具体模板书写与属性声明方式请以packages/fast-element包的入口导出与 模板绑定文档 为准。测试佐证过滤器行为是被显式验证的仓库内的 Playwright 测试为上述行为提供了直接证据children.pw.spec.ts 中的 gathers child nodes with a filter 用例构造 10 个foo-bar子元素以new ChildrenDirective({ property: nodes, filter: elements(foo-bar) })创建指令并绑定后断言model.nodes与children.filter(elements(foo-bar))长度相等、元素逐一相同证明filter确实按回调语义作用于原始节点数组同文件的 updates child nodes when they change 用例进一步验证在追加新子节点并等待更新队列后model.nodes会被重新计算并包含新增节点证明filter在每次变更重算时都会再次生效slotted.pw.spec.ts 的 gathers nodes from a slot with a filter 用例在 shadow DOM 中放入slot与 10 个foo-bar子元素同样以filter: elements(foo-bar)配置SlottedDirective断言绑定后属性值与过滤结果完全一致。这三类测试覆盖了初始收集过滤动态更新三条关键路径可以视为NodeBehaviorOptions行为契约的可执行文档。相关文档导航NodeBehaviorOptions 属性总览页filter 属性文档 与 property 属性文档ElementsFilter 类型文档接口与运行时实现node-observation.ts指令实现children.ts 与 slotted.ts行为验证children.pw.spec.ts 与 slotted.pw.spec.ts赞分享前端UI组件【免费下载链接】fastThe adaptive interface system for modern web experiences.项目地址https://gitcode.com/gh_mirrors/fa/fast点击查看免费下载相关推荐Fast-Element children() 指令详解在 FASTElement 中观察与同步子节点Fast Element children 指令详解在 FASTElement 中观察与同步子节点 children 是 microsoft/fast el前端UI组件深入解析 microsoft/fast-element 的 ChildrenBehaviorOptions子节点与子树观察的完整配置指南深入解析 microsoft/fast element 的 ChildrenBehaviorOptions子节点与子树观察的完整配置指南 导读 Childr前端UI组件FAST Element 的 SlottedBehavior 类详解基于 slotchange 的插槽节点观察运行时FAST Element 的 SlottedBehavior 类详解基于 slotchange 的插槽节点观察运行时 导读 SlottedBehavior 是前端UI组件上一篇ASP.NET Boilerplate 多数据库终极指南SQL Server、MySQL 与 PostgreSQL 配置详解下一篇Apache Doris配置迁移完全指南从基础配置到高级升级技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表