简体   繁体   中英

use ngFor loop in Angular 6 to dynamically create array of input elements and add dynamical validation based on template reference variables

I would like to create dynamically 3 input tags in Angular 6 to not copy/paste html code because that input elements have similar html and functionality.

For this purpose I created an array "reusableItems" inside component and initialize it :

    let numberOfInputElements = 3;        
    for (let i = 0; i < numberOfInputElements; i++) {          
      this.reusableItems.push({
        answer: 'Answer ' + (i +1),
        passwordRecoveryAnswer: this.user['passwordRecoveryAnswer' + (i + 1)]
      });
    }

Then I put code inside my html :

<div *ngFor="let item of dropDownDataManagerService.reusableItems" >
  <li class="col-xs-12 pl-lg pr0 pv-sm bd1-bottom">
    <div class="col-xs-4 ph0 pt"> {{item.answerTitle}}</div>
    <div class="col-xs-8">
      <input type="text" name={{item.answer}} ref-{{item.answer}}="ngModel" class="col-sm-12 k-textbox ph0"
             [(ngModel)]=item.passwordRecoveryAnswer
             [pattern]="[a-z]"
             required autocomplete="off"/>

    </div>
  </li>
</div>

It seems works fine but then I need to add error messages when these fields will be empty and not match to pattern. Something like :

<div *ngIf="__{{item.answer}}__.errors?.required ">
  {{'Please provide an answer' | translate}}
</div>
<div *ngIf="__{{item.answer}}__.errors?.pattern">
  {{'Pattern is not match'}}
</div>

I don't know what should i put inside ngIf condition. How can I do it if my template reference variables are comes from array? Is anyone have ideas?

Thanks

Angular creates unique template reference variable for each embedded template so that you can use the same template reference variable name inside ngFor loop:

<div *ngFor="let item of reusableItems">
    <li class="col-xs-12 pl-lg pr0 pv-sm bd1-bottom">
        <div class="col-xs-4 ph0 pt"> {{item.answerTitle}}</div>
        <div class="col-xs-8">
            <input type="text" name={{item.answer}} ref-answer="ngModel" class="col-sm-12 k-textbox ph0" [(ngModel)]="item.passwordRecoveryAnswer"
             [pattern]="'[a-z]'" required autocomplete="off" />
            <div *ngIf="answer.errors?.required">
                {{'Please provide an answer'}}
            </div>
            <div *ngIf="answer.errors?.pattern">
                {{'Pattern is not match'}}
            </div>
        </div>
    </li>
</div>

In the code above I use the same name for each input in array

ref-answer="ngModel" // or you can also use #answer="ngModel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM