大型动态表单实例整合 angular7 1-动态指令

大型动态表单:(分为4篇文章,已完结)

独白:
最近突然想要整理一下动态表单的相关知识,但是量太大,分散又不好理解。
我想尽量做到详细且结构清晰,容易记忆,所以只能慢慢整理,最后再调整一下结构。
限于本人尚才疏学浅,对于动态表单的理解也并非无所不能,如果有所偏差,希望可以得到一些建议

适用情况:
本案例介绍尽量适配于大量无冗杂操作逻辑的表单
尽量适用于表单的展示,当然也可以进行修改,但是如果仅是查看那就更加适配了。

结构

动态表单表单组件:动态组件集
在这里插入图片描述
与普通angular组件相同,动态表单也是一个模块,包含着模块应有的部分
模块中包含着组件:components,
页面:dynamic-form,
动态表单指令:dynamic-field.directive.ts,
动态表单module:dynamic-form.module.ts
在这里插入图片描述

动态指令

1、 开门见山,我们来看动态表单的核心指令 dynamic-field.directive.ts
话不多说,先上代码

import {
  Directive, Input, ComponentFactoryResolver, OnChanges,
  OnInit, Type, ViewContainerRef, ComponentRef
} from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormInputComponent } from './components/form-input/form-input.component';
import { FormSelectComponent } from './components/form-select/form-select.component';
import { FormDateComponent } from './components/form-date/form-date.component';
import { Field } from './models/field.interface';
import { FieldConfig } from './models/field-config.interface';
import { PublicService } from '../shared/services/public.service';
import { Logger } from '@app/core';
import { FormNgSelectComponent } from './components/form-ng-select/form-ng-select.component';
import { FormRadioComponent } from './components/form-radio/form-radio.component';
import { FormConfigInputComponent } from './components/form-config-input/form-config-input.component';
import { FormTextareaComponent } from './components/form-textarea/form-textarea.component';
import { FormConfigDateComponent } from './components/form-config-date/form-config-date.component';
import { HbLoginComponent } from '../login/component/hb-login/hb-login.component';
import { ScLoginComponent } from '../login/component/sc-login/sc-login.component';
import { FormInputCheckComponent } from './components/form-input-check/form-input-check.component';

// 动态加载组件
const components = {
  Input: FormInputComponent, // 文本框
  Date: FormDateComponent, // 日期
  SelectSingle: FormSelectComponent, // 下拉
  NgSelect: FormNgSelectComponent, // ng-select
  Radio: FormRadioComponent, // 单选
  Input2: FormConfigInputComponent,
  Textarea: FormTextareaComponent,
  Date2: FormConfigDateComponent, // 动态禁用日期
  ImgLogin: HbLoginComponent, // 无背景图登录组件
  BgLogin: ScLoginComponent, // 有背景图登录组件
  InputCheck: FormInputCheckComponent, // 带查询检测文本框

};

@Directive({
  selector: '[dynamicField]',
})
export class DynamicFieldDirective implements Field, OnChanges, OnInit {
  @Input() config: FieldConfig;
  @Input() group: FormGroup;
  @Input() model: any;
  log: Logger;
  dictionary: any;
  component: ComponentRef<Field>;
  constructor(
    private resolver: ComponentFactoryResolver,
    private container: ViewContainerRef,
    private publicService: PublicService,
  ) { }
 
  ngOnChanges() {
    if (this.component) {
      this.component.instance.config = this.config;
      this.component.instance.group = this.group;
      this.component.instance.model = this.model;
    }

  }
  ngOnInit() {
    const component = components[this.config.type];
    if (component) {
      const factory = this.resolver.resolveComponentFactory<any>(component);
      this.component = this.container.createComponent(factory);
      this.component.instance.config = this.config;
      this.component.instance.group = this.group;
      this.component.instance.model = this.model;
    }
  }
}

1、指令当中规定好了 动态加载组件 里面对应的组件是我们动态组件里的东西,后面会解释
2、指令当中接收(input)的三个值l分别代表着
config:本字段对应的字段配置,配置练习第二章
group: 本表单对应的表单formGroup 表单要求(必填,正则校验,默认值)
mode:字段绑定的ngModel 对象,整块表单的所有字段
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、component 属性
ComponentRef 类型:表示通过ComponentFactory创建的组件的实例,ComponentRef提供对组件实例的访问以及与此组件实例相关的其他对象,并允许您通过destroy方法销毁组件实例
4、构造函数中 包含了两个依赖注入
ComponentFactoryResolver:提供了一个方法resolveComponentFactory(),该方法接收一个组件类作为参数,生成一个基于该组件类的组件工厂。
ViewContainerRef:提供了一个方法 createComponent() ,该方法接收组件工厂作为参数,在该视图中生成子组件。
5、ComponentRef拥有的属性与方法:
C
location : ElementRef 组件实例的宿主元素所在的位置
injector : Injector 组件实例存在的注射器
instance : C 组件实例
hostview : ViewRef 组件实例的宿主视图ViewRef
changeDetectorRef : ChangeDetectorRef 组件的ChangeDetectorRef
componentType: Type 组件类型
destroy() : void 销毁组件实例及其附加数据
onDestroy(callback: Function) : void 允许注册将在组件销毁时调用的回调。

所以在ngOnChanges为组件添加config/group/model

6、在ngOnInit中定义 component 也就是哪种框(Input、date、select)
对应此弹窗的config需要在数据库中配置

// 动态加载组件
const components = {
  Input: FormInputComponent, // 文本框
  Date: FormDateComponent, // 日期
  SelectSingle: FormSelectComponent, // 下拉
  NgSelect: FormNgSelectComponent, // ng-select
  Radio: FormRadioComponent, // 单选
  Input2: FormConfigInputComponent,
  Textarea: FormTextareaComponent,
  Date2: FormConfigDateComponent, // 动态禁用日期
  ImgLogin: HbLoginComponent, // 无背景图登录组件
  BgLogin: ScLoginComponent, // 有背景图登录组件
  InputCheck: FormInputCheckComponent, // 带查询检测文本框
};

创建组件工厂,利用组件工厂在视图中生成子组件,并给子组件添加配置相关

const factory = this.resolver.resolveComponentFactory<any>(component);
this.component = this.container.createComponent(factory);
this.component.instance.config = this.config;
this.component.instance.group = this.group;
this.component.instance.model = this.model;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值