Pourquoi TypeScript me demande-t-il d'initialiser une propriété si j'obtiens sa valeur à partir d'une référence locale ?


Rouge d'Helsinki

Je viens de commencer à apprendre Angular.

Ceci est le modèle de mon composant personnalisé

    <div class="row">
  <div class="col-xs-12">
    <form action="">
      <div class="ro">
        <div class="col sm-5 form-group">
          <label for="name">Name</label>
          <input type="text" id="name" class="form-control" #nameInput />
        </div>
        <div class="col-sm-2 form-group">
          <label for="amount">Amount</label>
          <input type="number" id="amount" class="form-control" #amountInput />
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <button class="btn btn-success" type="submit" (click)="onAddItem()">
            Add
          </button>
          <button class="btn btn-danger" type="button">Delete</button>
          <button class="btn btn-primary" type="button">Clear</button>
        </div>
      </div>
    </form>
  </div>
</div>

Ceci est le fichier TypeScript respectif

import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-shopping-edit',
  templateUrl: './shopping-edit.component.html',
  styleUrls: ['./shopping-edit.component.css'],
})
export class ShoppingEditComponent implements OnInit {
  @ViewChild('nameInput') nameInputRef: ElementRef;
  @ViewChild('amountInput') amountInputRef: ElementRef;

  constructor() {}

  ngOnInit(): void {}
  onAddItem() {}
}

J'obtiens une erreur pour initialiser les variables nameInputRefet amountInputRef. Mais je reçois ces valeurs du formulaire. Comment puis-je résoudre ce problème ?

Eric Phillips

Typescript ne sait pas que vous récupérez ces valeurs à partir de quelque chose de défini dans le modèle. De plus, ils ne seront pas initialisés tant que la vue ne sera pas initialisée dans le cycle de vie angulaire, et vous tenterez peut-être d'y accéder alors qu'ils ne sont toujours pas définis.

La réponse à votre question est d'utiliser l'opérateur d'assertion non nul !, comme suit

export class ShoppingEditComponent implements OnInit {
 @ViewChild('nameInput') nameInputRef!: ElementRef;
 @ViewChild('amountInput') amountInputRef!: ElementRef;
}

Cependant, méfiez-vous que cela abuse de l'opérateur, car, comme mentionné, il est possible d'y accéder alors qu'il est encore indéfini.

Une deuxième méthode que vous pouvez utiliser consiste à développer le type pour autoriser undefined

@ViewChild('nameInput') nameInputRef: ElementRef | undefined;

Cependant, lors de l'accès à une propriété, vous devez utiliser l'opérateur d'assertion non nul

this.nameInputRef!.nativeElement

En passant, si ces éléments sont statiques dans votre composant (non soumis à *ngIf ou à tout rendu conditionnel), vous pouvez les marquer comme statiques. Cela vous permettra d'y accéder plus tôt dans le cycle de vie des composants, via ngOnInit.

@ViewChild('nameInput', { static: true }) nameInputRef: ElementRef;
@ViewChild('amountInput', { static: true }) amountInputRef: ElementRef;

Je marque toujours un ViewChildcomme statique s'il répond à ces critères afin d'y avoir accès le plus tôt possible dans le cycle de vie

Articles connexes