Jak ustawić domyślne wartości dla właściwości komponentu Angular 2?

102

Pisząc komponenty Angular 2.0, w jaki sposób można ustawić domyślne wartości właściwości?

Na przykład - Chcę ustawić fooaby 'bar'domyślnie, ale siła wiązania natychmiast rozwiązać się 'baz'. Jak to wygląda w hakach cyklu życia?

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

Biorąc pod uwagę następujące szablony, spodziewam się, że takie będą wartości. Czy się mylę?

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

Zalogowano do konsoli:

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

Zalogowano do konsoli:

'bar'
undefined
undefined
Bryan Rayner
źródło
Co się stanie, gdy spróbujesz?
JB Nizet
1
@BryanRayner sposób, w jaki obecnie drukowane są konsole, jest poprawny. Jaki jest problem, z którym się zmagasz?
Pankaj Parkar
6
Obecnie nie mam problemu, po prostu szukam wyjaśnienia na temat zamierzonego zachowania. Kiedy nie znalazłem odpowiedzi na swoją ciekawość, zdecydowałem, że zadam pytanie na wypadek, gdyby inni mieli to samo pragnienie jasności.
Bryan Rayner
W Twoim przykładzie brakuje nawiasu w @Input ()
kitimenpolku

Odpowiedzi:

142

To ciekawy temat. Możesz pobawić się dwoma hakami cyklu życia, aby dowiedzieć się, jak to działa: ngOnChangesi ngOnInit.

Zasadniczo, gdy ustawisz wartość domyślną na Input, oznacza to, że będzie ona używana tylko w przypadku, gdy nie będzie wartości nadejście do tego komponentu. Co ciekawe, zostanie to zmienione przed inicjalizacją komponentu.

Powiedzmy, że mamy takie komponenty z dwoma hakami cyklu życia i jedną właściwością pochodzącą z 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);
  }

}

Sytuacja 1

Komponent zawarty w html bez zdefiniowanej propertywartości

W rezultacie zobaczymy w konsoli: Init default

To znaczy, że onChangenie został uruchomiony. Init został wyzwolony, a propertywartość todefault zgodna z oczekiwaniami.

Sytuacja 2

Komponent zawarty w html z ustawioną właściwością <cmp [property]="'new value'"></cmp>

W rezultacie zobaczymy w konsoli:

Changed new value Object {}

Init new value

A ten jest interesujący. Najpierw wyzwalany był onChangehak, który był ustawiony propertyna new value, a poprzednia wartość była pustym obiektem ! I dopiero po tym, jak ten onInithak został uruchomiony z nową wartością property.

Mikki
źródło
8
Czy są jakieś linki do oficjalnej dokumentacji opisującej to zachowanie? Dobrze byłoby zrozumieć logikę i uzasadnienie tego, a także być w stanie śledzić zachowanie w poszczególnych wersjach.
Bryan Rayner,
Nie widziałem takich informacji, wszystko powyżej to moje własne dochodzenie. Myślę, że możesz znaleźć więcej odpowiedzi, jeśli przeczytasz skompilowane pliki js
Mikki
1
Szukałem dokumentacji na temat @Inputposiadania wartości domyślnych. @slicepan ma link do dokumentacji dotyczącej cyklu życia komponentu, ale nie widziałem wartości domyślnej używanej w dokumentacji.
nycynik
@nycynik po prostu użyj tego dla wartości domyślnych:@Input() someProperty = 'someValue';
magikMaker
1
Jesteś ratownikiem. Bolała mnie głowa podczas aktualizacji z aplikacji AngularJS do Angular 7.x
Andris
9

Oto najlepsze rozwiązanie tego problemu. (ANGULAR All Version)

Rozwiązanie adresowe : aby ustawić wartość domyślną dla zmiennej @Input . Jeśli żadna wartość nie zostanie przekazana do tej zmiennej wejściowej, przyjmie wartość domyślną .

Podałem rozwiązanie tego rodzaju podobnego pytania. Pełne rozwiązanie znajdziesz tutaj

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
źródło