Tengo un montón de campos de entrada en un bucle *ngFor. La documentación dice que las variables de referencia de plantilla deben ser únicas. ¿Hay alguna manera de hacer algo como #attendee-{{person.id}} para que sea único?

   <div *ngFor="let person of attendeesList">
       <input #attendee [ngModel]="person.name" (blur)="changeName(attendee.value)"/>
   </div>

(Sé que existe la opción de hacer (ngModelChange)="changeName($event)", pero hay razones por las que necesito utilizar desenfoque . Específicamente, no quiero que el modelo cambie hasta que la persona termine de escribir el nombre y hayamos validado que el nombre no está vacío y no es un nombre duplicado.

20
florentine 19 ene. 2018 a las 21:59

3 respuestas

La mejor respuesta

Su variable de referencia de plantilla ya es única porque la usa dentro del alcance de la vista incrustada:

<div *ngFor="let person of attendeesList">
  <input #attendee [ngModel]="person.name" (blur)="person.name = attendee.value"/>
</div>

Ejemplo de trabajo

Pero incluso puede omitir la variable de referencia de plantilla como se muestra a continuación:

<div *ngFor="let person of attendeesList">
  <input [ngModel]="person.name" (blur)="person.name = $event.target.value"/>
</div>
25
yurzui 19 ene. 2018 a las 19:23

Las variables de plantilla deben ser únicas con respecto a la plantilla en lugar de la representación de la plantilla (los valores reales). Desea utilizar ViewChildren.

@ViewChildren('attendee') attendeeInputs: QueryList<ElementRef>;

Puede tratar attendeeInputs como QueryList y operar en cada entrada de asistente individualmente según sea necesario según en iteración de los índices.

17
Explosion Pills 19 ene. 2018 a las 19:07

Si tiene una serie iterable de Entradas en su formulario y una buena cantidad de lógica con respecto a cómo desea que el formulario responda a la entrada del usuario, ReactiveFormsModule será mucho mejor. De esta manera, no tiene que preocuparse por las variables de referencia de plantilla y puede interactuar directamente con los controles de formulario.

Esencialmente con los formularios reactivos se vería algo así

Componente

// Initialize your Form
initForm(): void {
    this.Form = this._FormBuilder.group({
        arrayOfInputs: this._FormBuilder.array(initArray())
    })
}

// Initialize the Array of Inputs 
initArray(): FormGroup[] {
    return [
        { this._FormBuilder.group({ inputValue: [''] }),
        { this._FormBuilder.group({ inputValue: [''] }),
        { this._FormBuilder.group({ inputValue: [''] })
    ]
}

Plantilla

<ng-container formArrayName="formArray">
    <div [formGroupName]="i" *ngFor="let Inputs of Form.get('arrayOfInputs').controls; let i=index">
        <input formControlName="inputValue" type="text">
    </div>
</ng-container>

Aquí faltan algunas cosas, pero generalmente así es como construyo formularios que tienen entradas interables. La principal diferencia es que generalmente cuando inicializo el FormArray, estoy usando datos extraídos de algún lugar. Realmente ayuda a construir sus formularios en fragmentos lógicos.

Formas reactivas

3
joshrathke 19 ene. 2018 a las 21:04