【问题标题】:Angular dynamic html at the click of a buttonAngular 动态 html 只需单击一个按钮
【发布时间】:2021-05-15 19:10:42
【问题描述】:

我正在 Angular 中创建一个 HTML 表单。我遇到了一个问题。我希望能够通过单击按钮显示带有新表单控件的 HTML 块的副本。 这是现在的样子:

我希望用户能够单击标记为Click me 的按钮,并拥有HTML 块显示的副本,但具有不同的表单控件。你们对我如何做到这一点有什么建议吗?这是我目前所拥有的。

import { Component, OnInit, Directive, ViewChild } from '@angular/core';
import { FormControl, FormGroupDirective, NgForm, Validators, FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-questions',
  templateUrl: './questions.component.html',
  styleUrls: ['./questions.component.scss']
})

export class QuestionsComponent implements OnInit {
  jobForm: FormGroup = this.fb.group({
    companyName: this.fb.control('', [Validators.required ]),
    position: this.fb.control('', [Validators.required ]),
    description: this.fb.control('', [Validators.required ]),
    startDate: this.fb.control('', [Validators.required ]),
    endDate: this.fb.control('', [Validators.required ])
  });
  constructor(private readonly fb: FormBuilder) { }

  ngOnInit(): void {
  }  
  
  displayForm() {
    console.log(this.jobForm);
  }


}
<h3>Education:</h3>
    <form [formGroup]="jobForm">
      <mat-form-field >
        <mat-label>Company Name: </mat-label>
        <input matInput type="text" formControlName="companyName"/>
        <mat-error *ngIf="jobForm.controls.companyName.errors">Company name is required</mat-error>
      </mat-form-field>
      <mat-form-field >
        <mat-label>Position: </mat-label>
        <input matInput type="text" formControlName="position"/>
        <mat-error *ngIf="jobForm.controls.position.errors">Position is required</mat-error>
      </mat-form-field>
      <mat-form-field >
        <mat-label>Select start and end date:</mat-label>
        <mat-date-range-input [rangePicker]="picker">
          <input matStartDate placeholder="Start date" formControlName="startDate">
          <input matEndDate placeholder="End date" formControlName="endDate">
        </mat-date-range-input>
        <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
        <mat-date-range-picker #picker></mat-date-range-picker>
      </mat-form-field>
      <mat-form-field >
        <mat-label>Description: </mat-label>
        <textarea matInput type="text" formControlName="description"></textarea>
        <mat-error *ngIf="jobForm.controls.description.errors">Job description is required</mat-error>
      </mat-form-field>
    </form>
    <button (click)="displayForm()">Click me</button>

在用户点击click me 按钮 ID 后,喜欢生成一个重复的表单,以便他们填写详细信息。

谢谢

【问题讨论】:

    标签: javascript html css angular


    【解决方案1】:

    如果你可以使用Lodash 库就很容易了


    //const newjobFormGroup = _.cloneDeep(jobForm) as FormGroup;
    
    CopyJobForm(toCopyForm: FormGroup){
     //return _.cloneDeep(jobForm) as FormGroup;
     return _.cloneDeep(FormGroup) as FormGroup;
    }
    

    或者

    full deep clone的这个答案

    /**
     * Deep clones the given AbstractControl, preserving values, validators, async validators, and disabled status.
     * @param control AbstractControl
     * @returns AbstractControl
     */
    export function cloneAbstractControl<T extends AbstractControl>(control: T): T {
      let newControl: T;
    
      if (control instanceof FormGroup) {
        const formGroup = new FormGroup({}, control.validator, control.asyncValidator);
        const controls = control.controls;
    
        Object.keys(controls).forEach(key => {
          formGroup.addControl(key, cloneAbstractControl(controls[key]));
        })
    
        newControl = formGroup as any;
      }
      else if (control instanceof FormArray) {
        const formArray = new FormArray([], control.validator, control.asyncValidator);
    
        control.controls.forEach(formControl => formArray.push(cloneAbstractControl(formControl)))
    
        newControl = formArray as any;
      }
      else if (control instanceof FormControl) {
        newControl = new FormControl(control.value, control.validator, control.asyncValidator) as any;
      }
      else {
        throw new Error('Error: unexpected control value');
      }
    
      if (control.disabled) newControl.disable({emitEvent: false});
    
      return newControl;
    }
    

    【讨论】:

      【解决方案2】:

      我相信您所要求的是一种将表单组动态添加到页面的方法。如果是这种情况,那么下面的解决方案应该会有所帮助。

      您可以使用*ngFor 结构指令来迭代FormGroup 数组。需要进行以下调整:

      import { Component, OnInit, Directive, ViewChild } from '@angular/core';
      import { FormControl, FormGroupDirective, NgForm, Validators, FormBuilder, FormGroup } from '@angular/forms';
      
      @Component({
        selector: 'app-questions',
        templateUrl: './questions.component.html',
        styleUrls: ['./questions.component.scss']
      })
      
      export class QuestionsComponent implements OnInit {
      
        jobForms: FormGroup[] = []; // Declare an empty array
      
        constructor(private readonly fb: FormBuilder) { }
      
        ngOnInit(): void {
          this.addFormRow(); // Add an empty form group to the array
        }  
        
        //displayForm() {
        //  console.log(this.jobForm);
        //}
      
        // Add an additional row to the jobForms array - to be called from the template
        addFormRow() {
          this.jobForms.push(this.fb.group({
            companyName: this.fb.control('', [Validators.required ]),
            position: this.fb.control('', [Validators.required ]),
            description: this.fb.control('', [Validators.required ]),
            startDate: this.fb.control('', [Validators.required ]),
            endDate: this.fb.control('', [Validators.required ])
          }));
        }
      }
      
      <h3>Education:</h3>
      
          <form *ngFor="let formGroup of jobForms" 
                [formGroup]="formGroup">
            <mat-form-field >
              <mat-label>Company Name: </mat-label>
              <input matInput type="text" formControlName="companyName"/>
              <mat-error *ngIf="jobForm.controls.companyName.errors">Company name is required</mat-error>
            </mat-form-field>
            <mat-form-field >
              <mat-label>Position: </mat-label>
              <input matInput type="text" formControlName="position"/>
              <mat-error *ngIf="jobForm.controls.position.errors">Position is required</mat-error>
            </mat-form-field>
            <mat-form-field >
              <mat-label>Select start and end date:</mat-label>
              <mat-date-range-input [rangePicker]="picker">
                <input matStartDate placeholder="Start date" formControlName="startDate">
                <input matEndDate placeholder="End date" formControlName="endDate">
              </mat-date-range-input>
              <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
              <mat-date-range-picker #picker></mat-date-range-picker>
            </mat-form-field>
            <mat-form-field >
              <mat-label>Description: </mat-label>
              <textarea matInput type="text" formControlName="description"></textarea>
              <mat-error *ngIf="jobForm.controls.description.errors">Job description is required</mat-error>
            </mat-form-field>
          </form>
          <!-- Call addFormRow() to add a FormGroup to the array -->
          <button (click)="addFormRow()">Click me</button>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-06
        • 2019-05-02
        • 1970-01-01
        • 1970-01-01
        • 2016-10-07
        • 2018-03-03
        • 2015-11-16
        • 2020-09-27
        相关资源
        最近更新 更多