【问题标题】:How to create a custom control in a template driven form to render correctly?如何在模板驱动的表单中创建自定义控件以正确呈现?
【发布时间】:2019-02-13 16:08:44
【问题描述】:

问题:我可以让自定义控件呈现绑定ngModel 的值,或者我可以让验证按预期“冒泡”。

我的自定义文本组件有一个必需的属性,该属性在该层上受到尊重,但除非我使用 viewProvider,否则父级不知道它。但是当使用 viewProvider 时,我没有任何渲染。

我创建了一个堆栈闪电战,其中包含一个运行示例来说明我的意思。 请找到 custom-text 组件并尝试使用 viewProvider 已评论和未评论的表单。

https://stackblitz.com/edit/angular-fail-to-render

我很想了解我做错了什么以及如何在表单和自定义控件之间实现这种通信。

【问题讨论】:

  • 我尝试了不使用 viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], 的解决方案,但是如果没有这个,我看不到自定义表单组件的任何类型的通信。它的 ngModel 是未定义的。

标签: angular validation


【解决方案1】:

this response添加提供:NG_VALIDATORS,删除所需并添加验证功能,如

public setDisabledState?(isDisabled: boolean): void { }
validate(control:any){
    return this.model?null:{required:true}
  }

your forked stackblitz

更新 当我们使用带有 [(ngModel)] 的字符串数组(或数字数组)时会出现问题。

这行不通

  {{model.loopValues|json}}
  //NOT WORK
  <div *ngFor="let n of model.loopValues; let i = index;">
    <input [(ngModel)]="n" 
        name="{{'ct'+i}}" #control="ngModel"></custom-text>
  </div>

因为 ngModel 绑定在临时变量“n”上,所以不起作用。如果 model.loopValues 是一个对象数组,那么这项工作是因为绑定了对象的“内存位置”。

我们可以考虑一下

  //NOT WORK
  <div *ngFor="let n of model.loopValues; let i = index;">
    <input [(ngModel)]="model.loopValues[i]" 
          name="{{'ct'+i}}" #control="ngModel"></custom-text>
  </div>

并且不起作用,因为当我们更改输入时,由于 Angular 再次渲染 *ngFor 而失去焦点

我的想法在.ts中有一个与model.loopValues长度相同的数组

  array=new Array(this.model.loopValues.length)

现在我们可以做

<div *ngFor="let n of array; let i = index;">
    <custom-text [(ngModel)]="model.loopValues[i]" 
      name="{{'ct'+i}}" #control="ngModel"></custom-text>
</div>

奖励:我们可以使用repeat directive 并写一些喜欢

<div *repeat="model.loopValues.length;let i">
    <custom-text [(ngModel)]="model.loopValues[i]" 
      name="{{'ct'+i}}" #control="ngModel"></custom-text>
</div>

【讨论】:

  • 感谢您的提示!我将检查 validate 方法并查看它是否适用于我的实际代码库。我的场景比这个 stackblitz 示例要复杂一些:)
  • angular.io/api/forms/Validatorangular.io/api/forms/NG_VALIDATORS 有基于您的建议的示例 :) 我认为这会很好,感谢您指出这一点!
  • 也不能使用普通输入。 (抱歉现在已经很晚了,如果我有时间,我会试着知道为什么会这样)
  • 我很感激 :) 我一直在使用 Angular 遇到这些奇怪的场景,最终需要花费数小时的研究和反复试验。
  • 我更新了我的答案,试图解释为什么 ngModel 和字符串数组会导致问题。注意:这不是官方的,这只是我对这个主题的个人看法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 2012-11-09
  • 2018-03-12
  • 1970-01-01
  • 2013-09-09
  • 1970-01-01
相关资源
最近更新 更多