Come impostare i valori di default per le proprietà del componente Angular 2?


102

Quando si scrivono componenti Angular 2.0, come si impostano i valori predefiniti per le proprietà?

Ad esempio, desidero impostare foosu 'bar'per impostazione predefinita, ma l'associazione potrebbe risolversi immediatamente a 'baz'. Come si svolge questo negli hook del ciclo di vita?

@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);
    }
}

Dati i seguenti modelli, questo è ciò che mi aspetto che i valori siano. Ho sbagliato?

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

Accesso alla console:

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

Accesso alla console:

'bar'
undefined
undefined

Cosa succede quando lo provi?
JB Nizet

1
@BryanRayner il modo in cui le console attualmente vengono stampate sono corrette .. qual è il problema che stai affrontando?
Pankaj Parkar

6
Al momento non sto affrontando un problema, sto solo cercando chiarimenti sul comportamento previsto. Quando non ho trovato la risposta alla mia curiosità, ho deciso che avrei posto la domanda nel caso altri avessero lo stesso desiderio di chiarezza.
Bryan Rayner

Nel tuo esempio ti manca la parentesi su @Input ()
kitimenpolku

Risposte:


142

Questo è un argomento interessante. Puoi giocare con due hook del ciclo di vita per capire come funziona: ngOnChangese ngOnInit.

Fondamentalmente quando si imposta il valore predefinito su Inputquesto significa che verrà utilizzato solo nel caso in cui non ci sarà alcun valore in arrivo su quel componente. E la parte interessante sarà cambiata prima che il componente venga inizializzato.

Supponiamo di avere tali componenti con due hook del ciclo di vita e una proprietà proveniente da 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);
  }

}

Situazione 1

Componente incluso in html senza propertyvalore definito

Come risultato vedremo in console: Init default

Questo significa che onChangenon è stato attivato. Init è stato attivato e il propertyvalore è defaultquello previsto.

Situazione 2

Componente incluso in html con proprietà settata <cmp [property]="'new value'"></cmp>

Come risultato vedremo in console:

Changed new value Object {}

Init new value

E questo è interessante. In primo luogo è stato attivato un onChangehook, impostato propertysu new value, e il valore precedente era un oggetto vuoto ! E solo dopo che l' onInithook è stato attivato con il nuovo valore di property.


8
Esistono collegamenti ai documenti ufficiali per questo comportamento? Sarebbe bene capire la logica e il ragionamento alla base di questo, anche essere in grado di tracciare quale è il comportamento per versione.
Bryan Rayner

Non ho visto tali informazioni, tutto sopra è la mia indagine. Penso che tu possa trovare più risposte se leggerai file js compilati
Mikki

1
Stavo cercando documentazione sui @Inputvalori predefiniti. @slicepan ha un collegamento alla documentazione per il ciclo di vita del componente, ma non ho visto un valore predefinito utilizzato nella documentazione.
nycynik

@nycynik usa semplicemente questo per i valori predefiniti:@Input() someProperty = 'someValue';
magikMaker

1
Sei salvavita. Questo mi ha fatto male alla testa, mentre passavo dall'app AngularJS ad Angular 7.x
Andris

9

Ecco la soluzione migliore per questo. (ANGOLARE Tutte le versioni)

Soluzione di indirizzamento : impostare un valore predefinito per la variabile @Input . Se nessun valore è passato a quella variabile di input, prenderà il valore predefinito .

Ho fornito una soluzione per questo tipo di domanda simile. Puoi trovare la soluzione completa da qui

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);
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.