¿Cómo establecer valores predeterminados para las propiedades del componente Angular 2?

102

Al escribir componentes de Angular 2.0, ¿cómo se establecen los valores predeterminados para las propiedades?

Por ejemplo - Quiero conjunto fooa 'bar'por defecto, pero la fuerza vinculante de inmediato a resolver 'baz'. ¿Cómo se desarrolla esto en los ganchos del ciclo de vida?

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

Dadas las siguientes plantillas, esto es lo que espero que sean los valores. ¿Me equivoco?

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

Registrado en la consola:

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

Registrado en la consola:

'bar'
undefined
undefined
Bryan Rayner
fuente
¿Qué pasa cuando lo pruebas?
JB Nizet
1
@BryanRayner la forma en que se imprimen actualmente las consolas es correcta ... ¿cuál es el problema al que se enfrenta?
Pankaj Parkar
6
Actualmente no estoy enfrentando un problema, solo busco una aclaración sobre el comportamiento previsto. Cuando no encontré la respuesta a mi curiosidad, decidí hacer la pregunta en caso de que otros tuvieran el mismo deseo de claridad.
Bryan Rayner
En su ejemplo, le faltan el paréntesis en @Input ()
kitimenpolku

Respuestas:

142

Ese es un tema interesante. Puede jugar con dos ganchos del ciclo de vida para descubrir cómo funciona: ngOnChangesy ngOnInit.

Básicamente, cuando establece el valor predeterminado en Input, significa que se usará solo en caso de que no haya ningún valor en ese componente. Y la parte interesante se cambiará antes de que se inicialice el componente.

Digamos que tenemos dichos componentes con dos enlaces de ciclo de vida y una propiedad procedente 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);
  }

}

Situación 1

Componente incluido en html sin propertyvalor definido

Como resultado veremos en consola: Init default

Eso significa que onChangeno se activó. Init se activó y el propertyvalor es el defaultesperado.

Situación 2

Componente incluido en html con propiedad configurada <cmp [property]="'new value'"></cmp>

Como resultado veremos en consola:

Changed new value Object {}

Init new value

Y este es interesante. En primer lugar, se activó el onChangegancho, que se estableció propertyen new value, ¡y el valor anterior era un objeto vacío ! Y solo después de que ese onInitgancho se activó con un nuevo valor de property.

Mikki
fuente
8
¿Hay enlaces a los documentos oficiales para este comportamiento? Sería bueno entender la lógica y el razonamiento detrás de esto, también poder rastrear cuál es el comportamiento por versión.
Bryan Rayner
No he visto esa información, todo lo anterior es mi propia investigación. Creo que puede encontrar más respuestas si lee archivos js compilados
Mikki
1
Estaba buscando documentación sobre los @Inputvalores predeterminados. @slicepan tiene un enlace a los documentos para el ciclo de vida del componente, pero no vi un valor predeterminado utilizado en la documentación.
nycynik
@nycynik simplemente use esto para los valores predeterminados:@Input() someProperty = 'someValue';
magikMaker
1
Eres un salvavidas. Esto hizo que me doliera la cabeza, mientras actualizaba de la aplicación AngularJS a Angular 7.x
Andris
9

Aquí está la mejor solución para esto. (ANGULAR Todas las versiones)

Solución de direccionamiento : para establecer un valor predeterminado para la variable @Input . Si no se pasa ningún valor a esa variable de entrada, tomará el valor predeterminado .

He proporcionado una solución para este tipo de pregunta similar. Puede encontrar la solución completa desde aquí

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
fuente