Wie werden Standardwerte für Angular 2-Komponenteneigenschaften festgelegt?

93

Wie werden beim Schreiben von Angular 2.0-Komponenten Standardwerte für Eigenschaften festgelegt?

Zum Beispiel - ich mag Satz foozu 'bar'standardmäßig, aber die Bindung könnte sofort lösen zu 'baz'. Wie spielt sich das in den Lifecycle-Hooks ab?

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

Angesichts der folgenden Vorlagen erwarte ich folgende Werte. Liege ich falsch?

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

An der Konsole angemeldet:

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

An der Konsole angemeldet:

'bar'
undefined
undefined
Bryan Rayner
quelle
Was passiert, wenn Sie es versuchen?
JB Nizet
1
@BryanRayner Die Art und Weise, wie derzeit Konsolen gedruckt werden, ist korrekt. Was ist das Problem, mit dem Sie konfrontiert sind?
Pankaj Parkar
6
Ich stehe derzeit nicht vor einem Problem, sondern suche nur nach einer Klärung des beabsichtigten Verhaltens. Als ich keine Antwort auf meine Neugier fand, beschloss ich, die Frage zu stellen, falls andere den gleichen Wunsch nach Klarheit hatten.
Bryan Rayner
In Ihrem Beispiel fehlt Ihnen die Klammer auf dem @Input ()
kitimenpolku

Antworten:

128

Das ist ein interessantes Thema. Sie können mit zwei Lifecycle-Hooks herumspielen, um herauszufinden, wie es funktioniert: ngOnChangesund ngOnInit.

Wenn Sie den Standardwert auf diesen Wert setzen, Inputwird er grundsätzlich nur verwendet, wenn für diese Komponente kein Wert eingeht. Und der interessante Teil wird geändert, bevor die Komponente initialisiert wird.

Angenommen, wir haben solche Komponenten mit zwei Lifecycle-Hooks und einer Eigenschaft, von der sie stammen 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

In HTML enthaltene Komponente ohne definierten propertyWert

Als Ergebnis sehen wir in der Konsole: Init default

Das heißt, onChangewurde nicht ausgelöst. Init wurde ausgelöst und der propertyWert ist defaultwie erwartet.

Situation 2

In HTML enthaltene Komponente mit festgelegter Eigenschaft <cmp [property]="'new value'"></cmp>

Als Ergebnis sehen wir in der Konsole:

Changed new value Object {}

Init new value

Und dieser ist interessant. Zum einen war getriggerten onChangeHaken, die gefassten propertyzu new value, und früheren Wert war leer Objekt ! Und erst nachdem dieser onInitHook mit neuem Wert von ausgelöst wurde property.

Mikki
quelle
8
Gibt es Links zu den offiziellen Dokumenten für dieses Verhalten? Wäre gut, die Logik und die Argumentation dahinter zu verstehen, auch in der Lage zu sein, das Verhalten pro Version zu verfolgen.
Bryan Rayner
Ich habe solche Informationen nicht gesehen, alles oben ist meine eigene Untersuchung. Ich denke, Sie können mehr Antworten finden, wenn Sie kompilierte js-Dateien lesen
Mikki
1
Ich suchte nach Dokumentation zu den @InputStandardwerten. @slicepan hat einen Link zu den Dokumenten für den Komponentenlebenszyklus, aber ich habe keinen Standardwert in der Dokumentation gesehen.
Nycynik
@nycynik verwenden Sie einfach diese für Standardwerte:@Input() someProperty = 'someValue';
magikMaker
1
Du bist Lebensretter. Dies tat mir am Kopf weh, als ich von AngularJS App auf Angular 7.x
Andris
8

Hier ist die beste Lösung dafür. (WINKEL 7,8, 9)

Adressierungslösung : Zum Festlegen eines Standardwerts für die Variable @Input . Wenn an diese Eingabevariable kein Wert übergeben wird, wird der Standardwert verwendet .

Ich habe eine Lösung für diese Art von ähnlicher Frage bereitgestellt. Die vollständige Lösung finden Sie hier

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
quelle