如何在Angular的自定义控件组件中触摸内部控件?

     2023-03-13     55

关键词:

【中文标题】如何在Angular的自定义控件组件中触摸内部控件?【英文标题】:How to touch inner control in custom control component in Angular? 【发布时间】:2021-02-22 18:39:12 【问题描述】:

我有一个带有我自己的自定义控件组件的表单:

@Component(
  selector: "my-app",
  template: `
    <form [formGroup]="form">
      <app-custom-control formControlName="customControl"></app-custom-control>
    </form>

    <button (click)="touch()">
      Touch!
    </button>
  `,
  styleUrls: ["./app.component.css"]
)
export class AppComponent 
  form: FormGroup;

  constructor(private fb: FormBuilder) 

  ngOnInit() 
    this.form = this.fb.group(
      customControl: "1"
    );
  

  touch() 
    this.form.markAllAsTouched();
  

我的自定义控件组件内部有另一个自定义控件组件(在我的真实应用中需要它,因为外部控件组件有两种模式 - 读取和编辑):

@Component(
  selector: "app-custom-control",
  template: `
    <ng-select [ngModel]="value" [items]="items"></ng-select>
  `,
  styleUrls: ["./custom-control.component.css"],
  providers: [
    
      provide: NG_VALUE_ACCESSOR,
      useExisting: CustomControlComponent,
      multi: true
    
  ]
)
export class CustomControlComponent implements ControlValueAccessor, OnInit 
  items = ["1", "2"];

  value = null;
  onChange = (value: any) => ;
  onTouched = () => ;

  constructor() 

  registerOnChange(fn: any) 
    this.onChange = fn;
  

  registerOnTouched(fn: () => ): void 
    this.onTouched = fn;
  

  writeValue(outsideValue: number) 
    this.value = outsideValue;
  

可以将NG_VALIDATORS 添加到CustomControlComponent 并实现组件的验证方式(它只会提升ng-select 错误)。但是在包装表单的组件中执行this.form.markAllAsTouched() 时,我真的不知道如何触摸内部组件(ng-select)。

我尝试在 ngDoCheck 生命周期方法中进行操作,但它似乎运行了太多次,这是不可接受的解决方案。

游乐场:https://stackblitz.com/edit/angular-ivy-u3kdfj

【问题讨论】:

【参考方案1】:

在 github 中有几个相关的问题:

https://github.com/angular/angular/issues/10887 https://github.com/angular/angular/issues/17736

您可以做的是为 ControlValueAccessor 控件(outerControl)和内部 NgModel 控件(innerControl)获取 NgControl:

custom-control.component.ts

export class CustomControlComponent implements ControlValueAccessor, AfterViewInit 
  @ViewChild(NgControl) innerNgControl: NgControl;

  constructor(private inj: Injector) 

  ...

  ngAfterViewInit()  
    const outerControl = this.inj.get(NgControl).control;
    ...
  

然后你可以使用这个技巧绕过触摸状态到内部控制:

const prevMarkAsTouched = outerControl.markAsTouched;
outerControl.markAsTouched = (...args: any) =>  
  this.innerNgControl.control.markAsTouched();
  prevMarkAsTouched.bind(outerControl)(...args);
;

Forked Stackblitz

【讨论】:

如何在自定义控件中添加所需的星号?

...【发布时间】:2018-12-0920:48:51【问题描述】:我正在使用Angular6创建一个包含自定义表单控件的自定义组件。到目前为止,我已经在我的组件中实现了ControlValueAccessor。我的自定义控件是来自AngularMaterial的简单MatSelect组件。我想... 查看详情

如何使用 Angular 重置自定义表单控件

】如何使用Angular重置自定义表单控件【英文标题】:HowcanIresetacustomformcontrolwithAngular【发布时间】:2018-11-0921:54:04【问题描述】:我有一个带有验证的自定义表单控件。我在其中使用了一个独立的FormControl来处理值和一些验证。... 查看详情

如何在黑莓10中处理自定义控件的触摸事件

】如何在黑莓10中处理自定义控件的触摸事件【英文标题】:Howtohandletoucheventsofcustomcontrolinblackberry10【发布时间】:2013-08-2609:06:54【问题描述】:我有一个名为customContextMenu.qml的自定义控件,它的每一行都有一个图像和标签。我... 查看详情

Angular 2 - 单元测试绑定到嵌套的自定义表单控件

】Angular2-单元测试绑定到嵌套的自定义表单控件【英文标题】:Angular2-Unittestbindingtonestedcustomformcontrol【发布时间】:2018-01-1723:39:29【问题描述】:我有一个带有选择器app-date-picker的自定义控件。它实现了ControlValueAccessor。我有一... 查看详情

Angular2:例外:在控件上找不到指令注释

】Angular2:例外:在控件上找不到指令注释【英文标题】:Angular2:EXCEPTION:NoDirectiveannotationfoundonControl【发布时间】:2016-09-1115:39:39【问题描述】:我正在构建一个带有自定义验证的自定义输入字段组件,例如仅十进制数字、最小... 查看详情

如何在 iOS 中构建由现有控件组成的自定义控件?

】如何在iOS中构建由现有控件组成的自定义控件?【英文标题】:HowdoIbuildacustomcontrolmadeupofexistingcontrolsiniOS?【发布时间】:2013-11-0505:55:09【问题描述】:我正试图弄清楚在Xcode中来自visual-studio-land的“自定义控件”的等价物是什... 查看详情

实现 TComponentEditor 的自定义 Firemonkey 组件。在设计时将子控件添加到父控件

】实现TComponentEditor的自定义Firemonkey组件。在设计时将子控件添加到父控件【英文标题】:CustomFiremonkeyComponentthatimplementsTComponentEditor.Addchildcontroltoparentatdesigntime【发布时间】:2016-12-2414:38:31【问题描述】:我有一个自定义的FireMo... 查看详情

Angular 2 自定义表单输入

】Angular2自定义表单输入【英文标题】:Angular2customforminput【发布时间】:2016-04-2904:28:29【问题描述】:如何创建与原生&lt;input&gt;标签一样的自定义组件?我想让我的自定义表单控件能够支持ngControl、ngForm、[(ngModel)]。据我... 查看详情

验证不会传播到 Angular 中的自定义表单控件 ng-select

】验证不会传播到Angular中的自定义表单控件ng-select【英文标题】:ValidationisnotpropagatetoCustomFormControlng-selectinAngular【发布时间】:2020-06-1223:43:55【问题描述】:我在Angular9应用程序中使用带有自定义表单控件的反应式表单。我用... 查看详情

您如何在 WPF 中动态(通过代码)添加在 XAML 中制作的自定义控件?

】您如何在WPF中动态(通过代码)添加在XAML中制作的自定义控件?【英文标题】:Howdoyoudynamically(viacode)addcustomControlsthatweremadeinXAMLinWPF?【发布时间】:2019-07-1203:57:06【问题描述】:我已经通过VisualStduio(和Blend)构建了一个XAML... 查看详情

如何让其他控件在自定义控件中看到 DataTables 的集合?

】如何让其他控件在自定义控件中看到DataTables的集合?【英文标题】:HowtomakeothercontrolsseeacollectionofDataTablesinacustomcontrol?【发布时间】:2021-04-1209:26:54【问题描述】:我正在构建一个可以从工具箱拖到表单上的自定义组件。它公... 查看详情

SSIS:如何调试在脚本组件内部引用的自定义程序集

】SSIS:如何调试在脚本组件内部引用的自定义程序集【英文标题】:SSIS:Howtodebugacustomassemblythatisreferencedinsideofascriptcomponent【发布时间】:2021-12-3015:08:45【问题描述】:我能够调试通过VisualStudio的AttachtoProcess功能添加到SSIS的自定... 查看详情

如何制作可以添加到工具箱的自定义控件DLL?

】如何制作可以添加到工具箱的自定义控件DLL?【英文标题】:HowtomakecustomcontrolDLLwhichcanbeaddedontotoolbox?【发布时间】:2012-12-2704:48:48【问题描述】:我不知道该怎么称呼它。我制作了一个C#程序,其中包含VisualStudio工具箱的GUI控... 查看详情

如何使用 Angular 制作合适的容器组件?

】如何使用Angular制作合适的容器组件?【英文标题】:HowtomakepropercontainercomponentusingAngular?【发布时间】:2016-12-2409:57:25【问题描述】:在我从事的项目中,有“操作控件”列表,例如:此控件的部分在90%的页面上是相同的。所... 查看详情

为啥我的自定义用户控件的子项没有被初始化?

】为啥我的自定义用户控件的子项没有被初始化?【英文标题】:Whyarechildrenofmycustomuser-controlnotbeinginitialized?为什么我的自定义用户控件的子项没有被初始化?【发布时间】:2010-09-3013:28:58【问题描述】:更新:我一直在试验我... 查看详情

如何启用预定项目的下拉列表以添加到 SceneBuilder 中的自定义控件?

】如何启用预定项目的下拉列表以添加到SceneBuilder中的自定义控件?【英文标题】:HowtoenableadropdownlistofpredetermineditemstoaddtoacustomcontrolinSceneBuilder?【发布时间】:2018-03-1507:14:04【问题描述】:DialogPane在SceneBuilder中有这个实现:您... 查看详情

在 WPF C# 中无法访问用户控件的自定义属性

】在WPFC#中无法访问用户控件的自定义属性【英文标题】:CustomPropertyofUserControlnotaccessibleinWPFC#【发布时间】:2021-12-3112:38:48【问题描述】:我想使用C#在WPF中创建一个具有自定义属性(MyLabel)的自定义用户控件(UserControl),而无需... 查看详情

Angular:在 NgForm 的自定义输入组件中调用 markAsDirty()

】Angular:在NgForm的自定义输入组件中调用markAsDirty()【英文标题】:Angular:CallmarkAsDirty()inCustomInputComponentfromNgForm【发布时间】:2017-09-2405:07:58【问题描述】:我实现了一个自定义组件,它是NgModel输入的包装器。我将它们与ControlVa... 查看详情