web-dev-qa-db-fra.com

Comment accéder aux accesseurs getter / setter à partir de angular 4 dans la liaison de modèle?

Disons que j'ai les méthodes getter/setter suivantes

get next() {
  console.log(this.people[this._index], this._index);
  return this.people[this._index];
}

set next(i: any) {
  this._index = (+i) + 1;
  this._index = (+i) % this.people.length;
}

et je veux appeler cela de la manière suivante:

<ng-template ngFor let-person="$implicit" [ngForOf]="people" let-i=index let-last=last>
  <app-card [cardItem]="people[i]" [nextCard]="next(i)"></app-card>
</ng-template>

PS: Considérez cela comme un réseau circulaire. Où j'ai besoin des éléments précédents, actuels et suivants.

Cependant, j'obtiens l'erreur suivante

Angulaire: le membre "suivant" n'est pas appelable

Pourquoi donc? Et quelle est la solution?

Merci

Éditer

Merci les gars pour votre aide et explication. Avec votre aide, j'ai réussi à le faire fonctionner:

<app-card [currentCard]="people[i]" [nextCard]="people[i === people.length - 1 ? 0: i + 1]" [prevCard]="i == 0 ? people[people.length - 1] : people[i - 1]"></app-card>

Donc, son tableau à peu près circulaire. Supposons que nous ayons les éléments suivants:

people["James Dan", "Aluan Haddad", "Jota Toledo"]

Si peu de conditions:

  1. Si je me tiens au début du tableau (c'est-à-dire index = 0) - alors mon prev sera people[people.length - 1] qui est le dernier élément du tableau. Et si mon courant est sur l'index 1, alors mon précédent sera l'index 0 et le prochain sera l'index 2.
4
James

La syntaxe du modèle Angular est en général un sous-ensemble de la syntaxe JavaScript avec quelques différences notables et avec de nombreuses restrictions.

Cependant, ce que vous avez ici n'est pas non plus valide en JavaScript. Il n'est pas valide d'appeler un accesseur de propriété. Déjà.

Étant donné la propriété suivante

get p() {
  console.info('read p');
  return this.wrapped;
}
set p(value) {
  console.info('wrote p');
  this.wrapped = value;
}

L'accesseur get est invoqué implicitement lorsque la propriété ainsi nommée est lue.

Par exemple:

console.log(o.p); // read p

L'accesseur set est invoqué implicitement lorsque la propriété ainsi nommée est écrite.

Par exemple:

o.p = x; // wrote p;

Les mêmes règles s'appliquent dans les modèles Angular.

Cependant, votre exemple de

<app-card [cardItem]="people[i]" [nextCard]="next(i)">

suggère qu'une propriété n'est pas ce que vous voulez ici.

L'utilisation correcte d'une propriété implique la syntaxe suivante

<app-card [cardItem]="people[i]" [nextCard]="next = i">

Ce que je ne crois pas est pris en charge par la syntaxe du modèle Angular et même si cela n'a pas beaucoup de sens et serait difficile à lire.

Au lieu de cela, vous devez créer une méthode qui renvoie une valeur

getNext(i: number) {
  this._index = i + 1;
  this._index = i % this.people.length;
  return this.people[this._index];
}

Puis utilisé dans votre modèle comme

<app-card [cardItem]="people[i]" [nextCard]="getNext(i)">

Cela dit, je pense que l'ensemble du design est discutable. Vous semblez subir des contorsions pour stocker un état mutable en excès indépendamment de la matrice qui le maintient naturellement.

Je pense que vous seriez beaucoup mieux servi en supprimant entièrement la méthode et la propriété et en utilisant

<app-card
  *ngFor="let person of people; let i = index"
  [previousCard]="people[i === 0 ? people.length - 1 : i - 1]" 
  [cardItem]="person"
  [nextCard]="people[i === people.length - 1 ? 0 : i + 1]">

Si vous voulez une syntaxe plus propre, vous pouvez définir une propriété, avec un accesseur get uniquement, qui retourne une vue de votre tableau en tant qu'objets avec previous, current et next propriétés.

get peopleAsPreviousCurrentAndNextTriplets() {
  return this.people.map((person, i) => ({
    previous: this.people[i === 0 ? this.people.length - 1 : i - 1],
    current: person,
    next: this.people[i === this.people.length - 1 ? 0 : i + 1]
  }));
}

Cela peut être plus lisible dans un code complexe, car il résume l'index pour plus de propriétés sémantiques que nous pouvons utiliser directement. Peut-être plus important encore, il permet aux outils de classe mondiale de TypeScript de valider le calcul.

<app-card
  *ngFor="let item of peopleAsPreviousCurrentAndNextTriplets"
  [previousCard]="item.previous" 
  [cardItem]="item.current"
  [nextCard]="item.next">

Et ainsi nous bouclons la boucle. Notez comment nous définissons l'accesseur get et comment nous lisons la propriété qu'il définit sans (), invoquant implicitement cet accesseur.

Le dernier exemple est probablement exagéré pour ce scénario mais je pense qu'il est néanmoins utile.

13
Aluan Haddad