Comment définir les valeurs par défaut des propriétés du composant Angular 2?

93

Lors de l'écriture de composants Angular 2.0, comment définir les valeurs par défaut des propriétés?

Par exemple, je souhaite définir foosur 'bar'par défaut, mais la liaison peut être immédiatement résolue 'baz'. Comment cela se joue-t-il dans les hooks du cycle de vie?

@Component({  
    selector: 'foo-component'
})
export class FooComponent {
    @Input()
    foo: string = 'bar';

    @Input()
    zalgo: string;

    ngOnChanges(changes){
          console.log(this.foo);
          console.log(changes.foo ? changes.foo.previousValue : undefined);
          console.log(changes.foo ? changes.foo.currentValue : undefined);
    }
}

Étant donné les modèles suivants, c'est ce à quoi je m'attends que les valeurs soient. Ai-je tort?

<foo-component [foo] = 'baz'></foo-component>

Connecté à la console:

'baz'
'bar'
'baz'
<foo-component [zalgo] = 'released'></foo-component>

Connecté à la console:

'bar'
undefined
undefined
Bryan Rayner
la source
Que se passe-t-il lorsque vous l'essayez?
JB Nizet
1
@BryanRayner la façon dont les consoles sont actuellement imprimées est correcte ... quel est le problème auquel vous faites face?
Pankaj Parkar
6
Je ne suis actuellement pas confronté à un problème, je cherche juste des éclaircissements sur le comportement prévu. Quand je n'ai pas trouvé la réponse à ma curiosité, j'ai décidé de poser la question au cas où d'autres auraient le même désir de clarté.
Bryan Rayner
Dans votre exemple, il vous manque la parenthèse sur le @Input ()
kitimenpolku

Réponses:

131

C'est un sujet intéressant. Vous pouvez jouer avec deux hooks de cycle de vie pour comprendre comment cela fonctionne: ngOnChangeset ngOnInit.

Fondamentalement, lorsque vous définissez la valeur par défaut sur, Inputcela signifie qu'elle ne sera utilisée que dans le cas où aucune valeur ne viendrait sur ce composant. Et la partie intéressante, elle sera modifiée avant que le composant ne soit initialisé.

Disons que nous avons de tels composants avec deux hooks de cycle de vie et une propriété provenant de input.

@Component({
  selector: 'cmp',
})
export class Login implements OnChanges, OnInit {
  @Input() property: string = 'default';

  ngOnChanges(changes) {
    console.log('Changed', changes.property.currentValue, changes.property.previousValue);
  }

  ngOnInit() {
    console.log('Init', this.property);
  }

}

Situation 1

Composant inclus dans html sans propertyvaleur définie

En conséquence, nous verrons dans la console: Init default

Cela signifie qu'il onChangen'a pas été déclenché. Init a été déclenché et la propertyvaleur est defaultcelle attendue.

Situation 2

Composant inclus dans html avec propriété définie <cmp [property]="'new value'"></cmp>

En conséquence, nous verrons dans la console:

Changed new value Object {}

Init new value

Et celui-ci est intéressant. Tout d'abord onChange, le crochet a été déclenché , qui s'est établi propertyà new value, et la valeur précédente était un objet vide ! Et seulement après que ce onInithook ait été déclenché avec une nouvelle valeur de property.

Mikki
la source
8
Existe-t-il des liens vers les documents officiels pour ce comportement? Il serait bon de comprendre la logique et le raisonnement derrière cela, d'être également en mesure de suivre le comportement par version.
Bryan Rayner
Je n'ai pas vu de telles informations, tout ce qui précède est ma propre enquête. Je pense que vous pouvez trouver plus de réponses si vous lisez des fichiers js compilés
Mikki
1
Je cherchais de la documentation sur les @Inputvaleurs par défaut. @slicepan a un lien vers les documents pour le cycle de vie des composants, mais je n'ai pas vu de valeur par défaut utilisée dans la documentation.
nycynik
@nycynik utilise simplement ceci pour les valeurs par défaut:@Input() someProperty = 'someValue';
magikMaker
1
Vous êtes la bouée de sauvetage. Cela m'a fait mal à la tête, lors de la mise à niveau de l'application AngularJS vers Angular 7.x
Andris
8

Voici la meilleure solution pour cela. (ANGULAIRE 7,8, 9)

Solution d'adressage : pour définir une valeur par défaut pour la variable @Input . Si aucune valeur n'est passée à cette variable d'entrée, elle prendra la valeur par défaut .

J'ai fourni une solution pour ce genre de question similaire. Vous pouvez trouver la solution complète d' ici

export class CarComponent implements OnInit {
  private _defaultCar: car = {
    // default isCar is true
    isCar: true,
    // default wheels  will be 4
    wheels: 4
  };

  @Input() newCar: car = {};

  constructor() {}

  ngOnInit(): void {

   // this will concate both the objects and the object declared later (ie.. ...this.newCar )
   // will overwrite the default value. ONLY AND ONLY IF DEFAULT VALUE IS PRESENT

    this.newCar = { ...this._defaultCar, ...this.newCar };
   //  console.log(this.newCar);
  }
}
Parth Devloper
la source