技术长文 | Angular 响应式表单在 K8S 资源上的实践

2023-05-30 0 1,031

任正非:灵雀云后端合作开发技师,Kubernetes非官方街道社区 sig-ui 浓厚兴趣项目组(https://github.com/kubernetes/community/tree/master/sig-ui)。责任编辑为任正非同学以Angular积极响应式配置文件为例对Kubernetes成功经验的撷取和归纳。

节录:

Kubernetes 软件产业的普通用户日常生活工作中时常须要与 Deployment 等 Kubernetes 第一类碰触。熟识 Kubernetes 的好友单厢知道,Kubernetes 的第一类内部结构尽管倚重可扩展性,相同的第一类有著相近的内部结构设计经营理念,但即使是最娴熟的控制系统网络管理或是合作开发技师也不一定能将 Kubernetes 的第一类畅享。

为的是使普通用户更方便快捷的操作形式 Kubernetes 第一类,灵雀云的 Kubernetes 软件包后端介面提供更多了对普通用户亲善的 UI 配置文件软件控制系统。普通用户能通过 UI 配置文件更容易的撰稿 Kubernetes 第一类,与此同时还提供更多了 YAML 文件格式与 UI 配置文件动态Mandsaur的机能。

听众能先从这个Deployment配置文件demo里头领略动态Mandsaur的效用(注:该 demo 是为这首诗原则上合作开发,与灵雀云商品毫无关系):

技术长文 | Angular 响应式表单在 K8S 资源上的实践

症结

YAML 是 Kubernetes 第一类最常用的展现出和修正形式。对后端而言,倘若他们须要与此同时全力支持配置文件和 YAML 的形式撰稿 Kubernetes 天然资源,所以最后他们都得落回到撰稿  YAML 上。

从统计数据整体表现文件格式上上看,配置文件的数学模型统计数据是 JSON 第一类,而 YAML 为数组。YAML 与配置文件统计数据的Mandsaur,近似于文件格式化与反文件格式化的操作过程,他们须要在转化成的边界线借助于如js-yaml之类的库进行转换。

实际上统计数据形式的问题比较好解决,症结在于 YAML 所代表的 Kubernetes 天然资源第一类数学模型与配置文件统计数据进行转换的问题。课堂教学操作过程中,配置文件统计数据与 K8S 第一类Mandsaur有不少问题须要攻克。比如:

UI 配置文件状态与 K8S 第一类状态不一定是完全一致的,比方说:

他们不会或是不须要通过 UI 撰稿 K8S 的所有字段,非 UI 可撰稿字段在Mandsaur的时候能得到正确保留

UI 展现出的形式并非与 YAML 严格对应,比如 metadata 的 label 字段在 K8S 第一类 Schema 中整体表现为一个 StringMap,但在 UI 上整体表现为数组

针对实际业务场景,有时候会为 YAML 进行隐式的修正或是填充

配置文件字段嵌套层次深,与此同时配置文件字段之间可能有关联性

局部配置文件复用。 比如 Workload/Pod 相关的天然资源都能撰稿 PodSpec 或是 Container

动态同步配置文件与 YAML 内容,保证两种统计数据整体表现形式在任何时间点都是一致的

考虑到正确性与可维护性,这个机能点驱使他们的配置文件实现方案必须往单项统计数据流方向靠拢。

实现方案推导

模板驱动配置文件

每个 Angular 配置文件的合作开发者应该都碰触过模板驱动配置文件与积极响应式配置文件这两个相同的Angular配置文件实现思路。有些合作开发者可能会把积极响应式配置文件与动态配置文件混淆,实际上这两个概念没有什么联系。不熟识的同学能看看 Angular 官网这篇关于配置文件的介绍,其给出如下两者的区别:

一般而言:1)积极响应式配置文件更健壮:它们的可扩展性、可复用性和可测试性更强。 如果配置文件是应用中的关键部分,或是你已经准备使用积极响应式编程模式来构建应用,请使用积极响应式配置文件。2)模板驱动配置文件在往应用中添加简单的配置文件时非常有用,比如邮件列表的登记配置文件。它们很容易添加到应用中,但是不像积极响应式配置文件所以容易扩展。如果你有非常基本的配置文件需求和简单到能用模板管理的逻辑,请使用模板驱动配置文件。

用模板驱动配置文件写后端配置文件确实很容易:给定任意一个统计数据第一类,将须要的字段与模板的配置文件控件通过 [(ngModel)] 指令进行统计数据绑定;根据实际须要,再绑定一下诸如 required 的配置文件验证指令就完事了。鹅妹子嘤!

不过一旦这么做,普通用户就将统计数据的“权威”就交给了模板,脱离了统计数据的实际控制权,也就只能被动的接受来自于模板的统计数据更新、配置文件状态与生命周期、统计数据验证等事件。对复杂配置文件的业务逻辑,你很难通过这种模式扩展到大规模而复杂的配置文件统计数据逻辑处理之中。

积极响应式配置文件与受控组件

使用 Angular 积极响应式配置文件对初学者而言有些啰嗦和麻烦:为的是维护配置文件的状态,他们须要显式地创建一套完整的配置文件控制器第一类层级内部结构,并将此第一类通过 FormGroup / FormControl 之类的指令绑定到模板上的配置文件控件上。初看 Angular 的积极响应式配置文件的思想,似乎有点违背如今 MV* 的内部结构设计模式,因为它把一些本来能通过框架隐式管理的工作暴露给了合作开发者自己,额外的增加了不少工作量。

熟识 React 的配置文件控件实现的人应该了解React 的受控组件和非受控组件概念。通过受控组件,普通用户能通过单项统计数据流的思路,掌握配置文件控件统计数据的实际控制权。不过对实际的完整配置文件应用场景,普通用户还须要处理配置文件的提交状态、配置文件验证逻辑等信息。Angular 框架内置了一套相对成熟稳定的积极响应式配置文件软件控制系统,帮助合作开发者更可控的管理配置文件的状态的与此同时进行配置文件相关业务的合作开发。

Angular 配置文件控件的根基:Control Value Accessor

Angular 的配置文件控件的魔法与 React 的受控组件的思路十分类似,是典型的单项统计数据流的处理模式。另外,不管是模板驱动配置文件还是积极响应式配置文件,都是围绕着 ControlValueAccessor 接口内部结构设计实现的。

倘若一个组件提供更多了 NG_VALUE_ACCESSOR 令牌注入到模板的 DI 上下文,并实现了 ControlValueAccessor 接口,所以这个组件就能绑定任意 Angular 的配置文件指令。

ControlValueAccessor 最关键的有两点: registerOnChange 和 writeValue,这两个函数分别对应了单项统计数据流从配置文件内到外和从配置文件外到内两个方向的统计数据变化。

registerOnChange:初始化配置文件的操作过程中 Angular 会通过此接口,请求目标组件注册一个 onChange 回调。普通用户能通过这回调,从内到外,将配置文件控件的统计数据更新事件发射到控件外部,更新配置文件控件第一类的统计数据。

writeValue:Angular 的配置文件控件第一类更新时会主动调用此函数。能看成外部的统计数据状态流入配置文件内部。普通用户能自定义这次统计数据更新的作用,绑定到组件内部模板的配置文件控件上。

适配器模式

聪明的好友一定会注意到,Control Value Accessor 接口并没有要求 onChange 与 writeValue 调用的时候配置文件统计数据文件格式与输入一致。因此他们能在一个业务配置文件控件组件内实现局部的天然资源第一类与UI配置文件统计数据转换的逻辑。比方说上面提到的,他们能通过它实现一个键值对配置文件控件。

技术长文 | Angular 响应式表单在 K8S 资源上的实践

它对外暴露为正常的键值对控件,值类型为 { [key: string]: string }。 统计数据由外到内时,能通过 writeValue 将键值对通过 Object.entries 改变为 [string, string] 的数组,最后将绑定到配置文件内部的 FormArray 控件上;与此同时将内部状态改变时,在调用 onChange 之前将 [string, string][] 转化成为外部的 { [key: string]: string } 第一类类型。

倘若他们以配置文件控件为界限,这个界限的两侧分别为 Host 上绑定配置文件控件 NgControl 与配置文件控件内部的积极响应式配置文件。借助于 onChange 和 writeValue,他们能围绕着 Control Value Accessor 实现一个局部的适配器模式。

通过这个思路,他们能继续引申:

由于有了基于适配器模式的统计数据转化成思路, 对每一个配置文件控件,他们能通过 onChange 和 writeValue 这两个接口进行统计数据与配置文件的数学模型变化,实现UI的统计数据数学模型和实际对外暴露的统计数据数学模型的不一致需求。

针对一个复杂的天然资源第一类配置文件,他们能把问题拆解为多子配置文件控件组件,每一个子配置文件控件组件都去实现适配器模式。与此同时,每个子配置文件控件组件依然能用同样形式进行拆解组合。这样,通过将天然资源第一类不断往下递归拆解,借助于配置文件的组合和嵌套,他们能最后实现一个复杂的配置文件树。

内嵌配置文件的实现隔离了复杂配置文件的实现逻辑。每一个子配置文件控件尽管对外暴露是一个配置文件控件统计数据,但其内部是一个完整的配置文件。父级(host)组件能完全不了解子配置文件组件控件内部处理逻辑,比如配置文件的错误处理、统计数据转换等。与此同时由于K8s的内部结构设计,许多子配置文件是能在相同的天然资源里复用的,减轻了他们的合作开发成本。

配置文件控件本身在提供更多 K8s 统计数据的与此同时,也能整体表现为一个独立的 K8s 第一类天然资源。他们能把局部相关的业务逻辑完整的封装在此配置文件控件组件内部,做到神行合一。这点很重要,通过这一点,他们能更容易的划分出 K8s 天然资源的问题范围,更快做出代码内部结构的判断,减少合作开发的脑力负担和维护成本。

坊间也有其他合作开发者倾向于将业务处理逻辑独立出来,不放到组件内部,这样组件就能只负责薄薄一层视图渲染逻辑。我认为不是不可行,不过在复杂配置文件组件嵌套和复用角度,可能责任编辑采用的形式更容易维护。

由于上述实现思路操作过程有比较规范的思路,他们能内部结构设计出来一个标准的合作开发 K8s 天然资源第一类配置文件的实现范式。这个范式能大大降低合作开发人员对合作开发、维护复杂配置文件实现的思维负担。以上的操作过程借助于递归的思路,把一个问题拆解的简单又有效:

不管任何模式的复杂配置文件,能立刻开始着手合作开发

强调合作开发体验的共识、抽象与封装

避免合作开发出新的错误类型

Kubernetes第一类的积极响应式配置文件合作开发范式

中心思想

我归纳了这个合作开发范式里几个关键点:

神形合一:组件即是天然资源,也是配置文件控件

分形:局部子第一类配置文件组件处理与整体第一类配置文件组件处理保持一致

递归: 由于分形的特性,他们能用递归的形式自上而下,用统一的形式处理配置文件组件

问题隔离:一次只处理一个问题

积极响应式配置文件:严格执行单向统计数据流,同步处理,以达到动态同步的目的

流程

为任意一个 Kubernetes 第一类合作开发配置文件的操作过程能归纳如下:

1.学习目标 Kubernetes 第一类的基本机能, 对它的 YAML Schema 有基本概念。     a.由于他们后端人员对 YAML 字段的高透明度和充分的修正灵活度, 他们须要了解相关 k8s 第一类的业务/特性.2.书写目标 API 第一类 TypeScript 的类型 ( interface / type 等)。3.拆解 k8s 第一类类型成一系列子第一类,为每个可复用的子第一类封装为原则上的配置文件组件。a.比如 PodSpec, Container, Env 等4.为拆解出来的每个子第一类配置文件组件实现配置文件到第一类的Mandsaur。5.组合子第一类配置文件,最后组合成完整的 K8S 第一类配置文件

稍后他们会以部署配置文件为例,详细说明流程细节。

用例分析: Deployment 配置文件

熟识 Deployment 第一类的内部结构

首先参考官网对 Deployment 的 API 文档,输出一套 TypeScript 的接口,方便快捷后续参照:

技术长文 | Angular 响应式表单在 K8S 资源上的实践

部署配置文件拓扑

对部署配置文件,他们拆分为3个主要配置文件:

[DeploymentForm, PodSpecForm, ContainerForm]

技术长文 | Angular 响应式表单在 K8S 资源上的实践

K8s 天然资源第一类配置文件控件组件 – 模板

最外层组件,第一类的普通用户能依然使用模板驱动配置文件,将视图双向绑定到统计数据上:

技术长文 | Angular 响应式表单在 K8S 资源上的实践

内部模板书写上比较容易:由普通配置文件控件 (如select, input等) 和其他子第一类配置文件控件(如pod-spec-form)组成为一个原则上的配置文件。

部署模板使用积极响应式配置文件:

技术长文 | Angular 响应式表单在 K8S 资源上的实践

K8s 天然资源第一类配置文件控件组件 – 控制器

天然资源第一类组件控制器(也就是 TS 部分)的职责如下:

对外暴露为一个原则上的配置文件控件

Host 模板能绑定配置文件相关指令到第一类配置文件控件

对内整体表现为一个完整的配置文件组件

根据视图创建出一个配置文件控件树

协同各个配置文件控件,积极响应统计数据变化

使用单向统计数据流处理流入配置文件的统计数据

使用单向统计数据流处理流出配置文件的统计数据

组件初始化时,须要生成一个积极响应式配置文件控件树。根据实战,我归纳如下经验:

有且只有一个根部 form 控件第一类, 根据情况可能是 FormGroup 、FormArray、FormControl。但最后都要绑定到模板的 FormGroupDirective 指令上。

FormGroup 第一类内部结构一般与当前第一类 schema 内部结构相近,这样能

通过 form.patchValue 来设置配置文件统计数据

在控制器或是模板里更容易的与原始统计数据进行对照

在模板内能组合使用 formGroupName, formControlName 等指令绑定于积极响应配置文件控件

比如对部署配置文件,他们须要生成这样内部结构的配置文件控件:

技术长文 | Angular 响应式表单在 K8S 资源上的实践

控件须要对外暴露为一个普通的配置文件控件,与此同时将内部配置文件的错误向上传递到 Host 上的 NgControl 指令上。最关键的就是要实现 ControlValueAccessor 接口:

writeValue: 由外部写入内部时,须要将天然资源第一类适配为配置文件可用的数学模型内部结构。

大部分时候配置文件的 FormModel 与天然资源第一类的 schema 一致。

倘若业务须要,比如 k8s 的 metadata.labels 字段是 { [key: string]: string } 键值映射第一类,但在视图中他的配置文件数学模型是键值对数组 [string, string][],能在这个阶段进行统计数据适配。

onChange: 由内部写回外部时,须要将配置文件数学模型适配为天然资源第一类数学模型,与此同时将 UI 不可见的字段写回天然资源第一类数学模型中。

与此同时由于实现的原因,须要监听上层模板的 Form 指令,以得到提交嵌套模板的机能

setFormByResource 和 setResourceByForm

刚才提到,为配置文件设置天然资源第一类统计数据时能直接通过调用 form.patch Value(form Model) ,使得一个内部结构化的配置文件被能快速的填充。 有一个问题是,Angular 限制调用 patch Value 方法时 form Model 的 schema 必须是 form 内部结构的一个子集, 但通常来讲 form 的控制器内部结构有时候不须要覆盖完整的 schema (比如 status 字段等)。

我内部结构设计了 setForm By Resource 函数解决这个问题,方法伸缩。

而 setResource ByForm 函数与 setForm ByResource 作用相反。 在配置文件统计数据写回天然资源第一类时,利用它遍历配置文件层级控制器,将值设置到天然资源第一类上。通过 setResourceByForm, 他们还能做到从 UI 统计数据写回天然资源第一类时,不去触碰 UI 配置文件没有的字段,避免了统计数据转化成操作过程中统计数据可能会丢失的情况。

ng-resource-form-util 天然资源配置文件辅助工具库

配置文件的单项统计数据流基本上能用一张简单的图表示:

技术长文 | Angular 响应式表单在 K8S 资源上的实践

由于控制器大多数情况下使用形式和行为高度相近,于是灵雀云后端将配置文件的这些机能和行为抽象、封装到了 BaseResourceFormComponent 基类内,并将 代码开源在此。

上面的流程里还剩一些关键细节遗漏。我简要提一下思路,整理为如下Q&A:

Q: 配置文件是如何处理配置文件验证,或是甚至是异步配置文件验证逻辑,并向上传递配置文件验证状态的?A: 将内部配置文件的Q: 内部配置文件的提交逻辑如何处理?交事件Q: 有的配置文件内部有些统计数据不属于当前 Kubernetes 第一类。这种情况下如何处理?A: 借助于 ng-content 、TemplateRef 或是 Portal,将天然资源毫无关系模板映射到组件内。

你能通过 DEMO 和 DEMO 的源码继续了解一个比较完整的软件控制系统是怎样的。

写在最后

基于责任编辑配置文件合作开发范式,灵雀云的后端合作开发能非常快速的进行 K8s 相关天然资源第一类配置文件的实现,并且得到 YAML 与天然资源第一类Mandsaur的需求实现。

责任编辑介绍了一种通用的基于 Angular 积极响应式配置文件撰稿 K8s 第一类的实现思路与范式。实际上,这个思路并不只局限于 Angular 或是 K8s 第一类,听众甚至能根据自己的须要,将此文章的思路使用 final form 带入到 React 或是 Vue 应用之中。

感谢阅读!

相关阅读:

演讲实录 | 石油巨头如何与Kubernetes, DevOps共舞?

Jenkins创

演讲实录 | 灵雀云微服务和 K8S 集成探索课堂教学

实录:K8S的网络接口CNI及灵雀云的课堂教学

技术长文 | Angular 响应式表单在 K8S 资源上的实践

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务