Como definir os valores padrão para as propriedades do componente Angular 2?

93

Ao escrever componentes do Angular 2.0, como definir os valores padrão das propriedades?

Por exemplo - desejo definir foocomo 'bar'padrão, mas a ligação pode resolver imediatamente para 'baz'. Como isso funciona nos ganchos do 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);
    }
}

Dados os modelos a seguir, é o que eu espero que os valores sejam. Estou errado?

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

Registrado no console:

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

Registrado no console:

'bar'
undefined
undefined
Bryan Rayner
fonte
O que acontece quando você tenta?
JB Nizet
1
@BryanRayner a forma como os consoles estão sendo impressos atualmente estão corretos ... qual é o problema que você está enfrentando?
Pankaj Parkar
6
No momento, não estou enfrentando nenhum problema, apenas buscando esclarecimentos sobre o comportamento pretendido. Quando não encontrei a resposta para minha curiosidade, decidi que faria a pergunta caso outros tivessem o mesmo desejo de clareza.
Bryan Rayner
No seu exemplo está faltando o parêntese em @Input ()
kitimenpolku

Respostas:

130

Esse é um assunto interessante. Você pode brincar com dois ganchos de ciclo de vida para descobrir como funciona: ngOnChangese ngOnInit.

Basicamente, quando você define o valor padrão para Inputisso, ele será usado apenas no caso de não haver nenhum valor vindo desse componente. E a parte interessante é que será alterado antes que o componente seja inicializado.

Digamos que temos esses componentes com dois ganchos de ciclo de vida e uma propriedade proveniente 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);
  }

}

Situação 1

Componente incluso em html sem propertyvalor definido

Como resultado, veremos no console: Init default

Isso significa que onChangenão foi acionado. Init foi acionado e o propertyvalor é defaulto esperado.

Situação 2

Componente incluído em html com propriedade definida <cmp [property]="'new value'"></cmp>

Como resultado, veremos no console:

Changed new value Object {}

Init new value

E este é interessante. Em primeiro lugar foi desencadeada onChangegancho, que setado propertypara new value, eo valor anterior era objeto vazio ! E só depois que o onInitgancho foi acionado com o novo valor de property.

Mikki
fonte
8
Existe algum link para a documentação oficial desse comportamento? Seria bom entender a lógica e o raciocínio por trás disso, também ser capaz de rastrear qual é o comportamento por versão.
Bryan Rayner
Eu não vi essas informações, tudo acima é minha própria investigação. Acho que você pode encontrar mais respostas se ler os arquivos js compilados
Mikki
1
Eu estava procurando a documentação sobre como @Inputter valores padrão. @slicepan tem um link para os documentos do ciclo de vida do componente, mas não vi um valor padrão usado na documentação.
nycynik
@nycynik simplesmente use isso para valores padrão:@Input() someProperty = 'someValue';
magikMaker
1
Você é o salva-vidas. Isso fez minha cabeça doer, enquanto fazia a atualização do aplicativo AngularJS para o Angular 7.x
Andris
8

Aqui está a melhor solução para isso. (ANGULAR 7,8,9)

Solução de endereçamento : Para definir um valor padrão para a variável @Input . Se nenhum valor for passado para essa variável de entrada, ela assumirá o valor padrão .

Eu forneci solução para esse tipo de questão semelhante. Você pode encontrar a solução completa aqui

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
fonte