【问题标题】:How to set formControlNames using *ngFor in Angular?如何在 Angular 中使用 *ngFor 设置 formControlNames?
【发布时间】:2017-12-28 08:10:49
【问题描述】:

我正在尝试使用*ngFor 对数组中的对象设置表单控制。根据用户的不同,有时我会在 Array 中有 1 个对象,但有时会有多个。

我的问题是我想使用循环创建一个formControlName,但我不确定如何在组件中设置表单组验证器?像下面这样设置它们意味着如果只有 1 个对象,则表单在查找另一个不存在的 formControlName 时仍然无效。

因此,如果名称为“Days”的第一个对象不在列表中,“Days”仍会在 this.form 中并显示在控件中:

数组:

indicators = [
  {name:"Days",data:[250,1]},
  {name:"Multiply Average",data:[3,.25,1]}
],

组件:

ngOnInit() {
    this.form = this._fb.group({
            "Multiply Average":['', Validators.compose([
                Validators.required
                ])],
            "Days":['', Validators.compose([
                Validators.required
                ])],
        });  
    };

模板:

  <span
     *ngFor="let i of indicators">
          {{i.name}}: 
          <md-slider
            formControlName={{i.name}}
            color="primary"
            [max]=i.data[0]
            [thumb-label]="true"
            [step]=i.data[1]
            [min]=i.data[2]>
          </md-slider>
  </span>

任何帮助都会很棒

【问题讨论】:

  • @AJT_82 感谢您的回复。对不起,我应该更清楚。我希望能够将可变数量的字典传递给指标数组。我知道它目前适用于两个。如果我只传递{name:"Days",data:[250,1]},那么组件中仍然会有Multiply Average 的表单控制。该模板只有Days 的滑块。有没有办法像循环一样动态更新这两种方法?如果您不知道指标数组的长度,我不确定是否有可能?谢谢
  • 听起来你需要FormArray,但我不能再多说,因为我不确定数组的外观,也不知道data 数组是什么里面的对象是。预期的输出究竟是什么? formcontrol 应该持有什么值,只是名称?
  • 好的,谢谢。我现在会尝试做一个 plunkr 让它更清楚。我以前没做过,但应该可以解决
  • 我为整个组件做了一个plnkr.co/edit/3wg4SUncFbJ8r1OJ1nrf?p=info。所以基本上问题是用户选择要使用的股票指标,不同的指标将需要不同数量的滑块(用户输入)发送到我的 API。我知道您可以为每个单独的滑块编写代码,但如果可能的话我想使用循环?只是因为我不想每次在指标数组中添加另一个指标时都编写更多代码?代码更新了模板中的所有内容,但不知道如何根据所选指标使控件 FormBuilder 发生变化。干杯
  • 没有足够的代码来重现这个问题,例如你的数组的内容是什么。请设置示例数据,显示问题的示例数据,您问题中的当前indicators 没有?

标签: angular typescript angular-material2 ngfor


【解决方案1】:

确保您的form 标签上有[formGroup]="form"

为了使其更详细,使用属性绑定而不是对formControlName 属性进行插值

[formControlName]="i.name"

【讨论】:

    【解决方案2】:

    您需要的是条件验证。根据选择,您需要设置所需的验证器,或者然后删除它们。这是一个非常简单的例子,可以给你一个想法,如果你有更多的字段,更多的验证等,我建议你看看这个:"How to implement conditional validation in Angular model-driven forms"

    有一个通过表单控件进行迭代并使整个事情更加动态的示例,但想法与以下相同。

    我们可以在用户在md-select 中做出选择时设置更改事件。你当然也可以使用valueChanges,但我喜欢一个简单的更改事件:

    <md-select
      formControlName="indicator1"
      (change)="checkValue(form.get('indicator1'))">
      <md-option
          *ngFor="let indicator of indicators['indicatorlist']" 
           [value]="indicator">
           {{indicator}}
      </md-option>   
    </md-select>
    

    我们传递表单控件,以便我们可以将它与应该删除的验证器的值进行比较,以防它不匹配,在这种情况下,我们想要删除验证器是不是Above WMA - Volume Price。我们设置/取消设置验证器,我们还需要在这里使用updateValueAndValidity()

    checkValue(ctrl) {
      if(ctrl.value != "Above WMA - Volume Price") {
        this.form.get('Multiply Average').setValidators(null);
        this.form.get('Multiply Average').updateValueAndValidity();
      } else {
        this.form.get('Multiply Average').setValidators(Validators.required);
        this.form.get('Multiply Average').updateValueAndValidity();
      }
    }
    

    你也可以使用clearValidators()代替setValidators(null)

    如前所述,这是一个非常粗略的示例,仅供您参考。

    现在在 plunker 中,如果您从下拉列表中选择 Above WMA - Volume Price 以外的其他内容,则该表单现在将被视为有效(如果其他字段有效),即使该表单控件中没有名称为 @ 987654332@.

    演示: https://plnkr.co/edit/h4nQfg1VYykaGgfNfnWk?p=preview

    【讨论】:

    • 哇,非常感谢!我知道一定有办法,但不知道
    • 嘿,很高兴听到它成功了!是的,响应式表单有很多很酷的特性。你基本上可以用反应形式做任何事情,哈!只需要花点时间来掌握所有你能做的事情和所有内置的方法。:) 但是,周末愉快,编码愉快!
    • 是的,我对 Angular 还是比较陌生,所以仍然有很多发现!解决这个问题绝对是一个更好的周末结束哈哈,再次感谢
    猜你喜欢
    • 2016-09-10
    • 1970-01-01
    • 2021-04-25
    • 2017-01-13
    • 2020-01-01
    • 2021-06-02
    • 1970-01-01
    • 2019-11-23
    相关资源
    最近更新 更多