代码之家  ›  专栏  ›  技术社区  ›  Maniraj Murugan

以角度无功形式显示输入框状态

  •  0
  • Maniraj Murugan  · 技术社区  · 7 年前

    我正在做角6申请,我使用角反应形式。

    Html:

    <form [formGroup]="form">
    
        <h2>Click the add button below</h2>
        <button (click)="addCreds()">Add</button>
            <div formArrayName="credentials" *ngFor="let creds of form.controls.credentials?.value; let i = index">
              <div [formGroupName]="i" style="display: flex">
                <select (ngModelChange)="changeAction($event)" formControlName="action">
                  <option *ngFor="let option of options" value="{{option.key}}"> {{option.value}} </option>
                </select>
                <input placeholder="Name" formControlName="name">
                <div *ngIf="showLabel">
                <input placeholder="Label" formControlName="label">
                </div>
              </div>
            </div>
    
        </form>
    
        <pre>
          {{ form ?.value | json }}
        </pre>
    

    Ts:

      form: FormGroup;
      showLabel: boolean = false;
    
      options : any = [ 
        { "key" : "set", "value": "Set" },
        { "key" : "wait", "value": "Wait" },
        { "key" : "go", "value": "Go" }   
        ]
    
      constructor(private fb: FormBuilder) {
        this.form = this.fb.group({
          credentials: this.fb.array([]),
        });
      }
    
      addCreds() {
        const creds = this.form.controls.credentials as FormArray;
        creds.push(this.fb.group({
          action: '',
          name: '',
          label: ''
        }));
      }
    
      changeAction(e) {
        if(e === "set" || e === "go") {
          this.showLabel = true;
        } else {
          this.showLabel = false;
        }
      }
    

    工作堆叠: https://stackblitz.com/edit/angular-form-array-example-yksojj

    在这个示例中,将有一个“添加”按钮,单击该按钮后,您将得到一个 select-box 值为 set,wait,go 以及一个名为name的输入。单击“添加”按钮后,将添加同一行并形成数组中的每个对象。

    你也可以看到 if 标签的HTML内条件,

    <div *ngIf="showLabel">
      <input placeholder="Label" formControlName="label">
    </div>
    

    事物 我有需要 在选择框中,如果我选择 设置或走 然后需要显示标签,否则不应该显示我写的标签,

      changeAction(e) {
        if(e === "set" || e === "go") {
          this.showLabel = true;
        } else {
          this.showLabel = false;
        }
      }
    

    足够清楚 如果用户单击三次“添加”按钮,则只需显示下拉列表和名称字段三次,而如果用户从下拉列表中选择值为 设置或走 然后需要将标签输入显示到 仅在下拉列表中设置值并转到的特定行 …如果选择是 wait 那么下拉值为的行不应该有标签框 等待 .

    请帮助我达到预期的效果。

    4 回复  |  直到 7 年前
        1
  •  1
  •   Chellappan வ    7 年前

    如果将disabled:true属性添加到FormControl,它将从FormGroup中排除,则可以手动启用FormControl。

    creds.push(this.fb.group({
          action: '',
          name: '',
          label: {disabled:true, value: ""}
        }));
    

    然后使用启用方法启用

    changeAction(e,index) {
        if(e === "set" || e === "go") {
          this.showLabel = true;     
         this.form.get('credentials').at(index).get('label').enable();
    
        } else {
          this.showLabel = false;
          this.form.get('credentials').at(index).get('label').disable();
        }
      }
    

    例子: https://stackblitz.com/edit/angular-form-array-example-5buwyr

        2
  •  1
  •   Eliseo    7 年前

    请不要使用(ngmodelchange)或“changeaction($event)”来获取数组中控件的值。好的,ngmodelchange用于模板驱动的表单,而不是反应式表单。

    首先更改表单,使用带有formarayname=“credentials”的DIV和内部DIV*NGFOR=“let creds of form.get('credentials')创建表单。 控制

        <!--a div with formArrayName--->
        <div formArrayName="credentials" >
          <!--a div *ngFor over "controls", in this div don't forget formGroupName-->
          <div *ngFor="let creds of form.get('credentials').controls; let i = index" 
              [formGroupName]="i" style="display: flex">
              <select formControlName="action">
                 <option *ngFor="let option of options" value="{{option.key}}">
                   {{option.value}} 
                 </option>
              </select>
              <input placeholder="Name" formControlName="name">
              <div *ngIf="??????????????">
                 <input placeholder="Label" formControlName="label">
              </div>
          </div>
        </div>
    

    好吧,现在的情况。要获得“action”的值,可以使用

    form.get('credentials').at(i).value.action
    //or, better
    creds.value.action
    

    所以,你的DIV变成了

    <div *ngIf="creds.value.action=='set' ||
          creds.value.action=='go'">
      <input placeholder="Label" formControlName="label">
    </div>
    

    这个程序避免了.ts中不必要的代码。

        3
  •  1
  •   Jeremy Thille    7 年前
    this.showLabel
    

    这个变量的作用域是您的整个组件。因此,打开或关闭它将显示和隐藏所有输入。

    您需要每行值( creds.showLabel 或者在模板中使用:

    *ngIf="['set','go'].includes(creds.action)"
    

    Updated Stackblitz

    顺便说一下,这是:

    changeAction(e) {
        if(e === "set" || e === "go") {
          this.showLabel = true;
        } else {
          this.showLabel = false;
        }
      }
    

    用这种方式书写更优雅:

    changeAction(e) {
        this.showLabel = ['set','go'].includes(e)
    }
    

    或者这样:

    changeAction(e) {
        this.showLabel = e in ['set','go']
    }
    
        4
  •  0
  •   miiiii    7 年前

    好, Jeremy's answer 非常好,并且强制使用平台/语言提供的大多数本地API,但是,这里有一个 传统的 了解对象的实际流程和范围等的方法…

    根本原因: “显示隐藏”字段对组件范围是全局的,而不是根据 formgroup 水平。因此,更改单个值并对所有人使用将影响所有人。

    解决方案:

    1. 使用 杰瑞米 回答 对于干净的编码和较少出错的代码。

    2. 管理一个变量数组,该数组将负责显示/隐藏每个表单组的详细信息。

    在下面的答案中,为了便于理解,添加了一些注释,并添加了console.log来查看到底发生了什么。同样,使用索引 i 创建于 *ngFor 并展示了如何在未来利用这些东西。

    import { Component } from '@angular/core';
    import { FormControl, FormGroup, FormArray, FormBuilder } from '@angular/forms';
    
    @Component({
      selector: 'my-app',
      templateUrl: 'app.component.html',
    })
    export class AppComponent  {
      form: FormGroup ;
      showLabel = [];
      creds : FormArray; 
      options : any = [ 
        { "key" : "set", "value": "Set" },
        { "key" : "wait", "value": "Wait" },
        { "key" : "go", "value": "Go" }   
        ]
    
      constructor(private fb: FormBuilder) {
        
        this.form = this.fb.group({
          credentials: this.fb.array([]),
        });
        this.creds = this.form.controls.credentials as FormArray;
      }
    
      addCreds() {
        
        this.creds.push(this.fb.group({
          action: '',
          name: '',
          label: ''
        }));
        // every time adding new foem grp, adding lable sho/hide data also.
      this.showLabel.push(false);
    
      }
    
      changeAction(e, i) {
        //every time input clikced, managing show/hide for that particular data also
        console.log("iii", i, e.target.value);
        if( e.target.value == "set" ||  e.target.value == "go") {
          this.showLabel[i] = true;
        } else {
          this.showLabel[i] = false;
        }
      }
    
    }
    <form [formGroup]="form">
    
    	<h2>Click the add button below</h2>
    	<button (click)="addCreds()">Add</button>
            <div formArrayName="credentials" *ngFor="let creds of form.controls.credentials?.value; let i = index">
              <div [formGroupName]="i" >
                <select (change)="changeAction($event, i)" formControlName="action">
                  <option *ngFor="let option of options" value="{{option.key}}"> {{option.value}} </option>
                </select>
                <input placeholder="Name" formControlName="name">
                <div *ngIf="showLabel[i]">
                <input placeholder="Label" formControlName="label">
                </div>
              </div>
            </div>
    
        </form>
    
        <pre>
          {{ form ?.value | json }}
        </pre>

    See live stackblitz working code

    注: 传统的 意思是… 正如我们每次所做的,即独自处理我们的问题,并在我们身上创造新的问题来解决。 这不是传统。P