Angular componentes: passar por referência ou passar por valor?
No Angular, você pode passar dados do componente pai para o componente filho usando o decorador @Input() e um componente filho pode emitir um evento para um comentário pai usando o decorador @Output().
No Angular, você pode passar dados do componente pai para o componente filho usando o decorador @Input() e um componente filho pode emitir um evento para um comentário pai usando o decorador @Output(). Esta postagem do blog tem como objetivo explicar se ele é passado por referência ou valor de passagem no contexto de @Input() e @Output decorador.
Para começar, vamos supor que temos dois componentes Angular, conforme listado abaixo:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-video',
template: `
{{data.counter}} {{count}}
`
})
export class VideoComponent {
@Input() data: any;
@Input() count: number;
}
Como você vê, temos duas propriedades de entrada.
- Na propriedade data, passaremos um objeto.
- Na propriedade count, passaremos um número.
No AppComponent, estamos passando valor para ambas as propriedades, conforme mostrado abaixo:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-video [data]='data' [count]='count' ></app-video>
`
})
export class AppComponent implements OnInit {
data: any = {};
count: number;
constructor() {
}
ngOnInit() {
this.data.counter = 1;
this.count = 1;
}
}
Como você pode ver, estamos passando dados (objeto) e contagem (número) para o componente filho. Como os dados estão sendo passados como objeto, será "Passar por referência" e, como count é passado como número, será "Passar por valor".
Portanto, passar um objeto, matriz ou algo semelhante é Passar por Referência e, para tipos primitivos como número, é Passar por Valor.
Para entendê-lo melhor, vamos gerar dois eventos no componente filho, conforme mostrado na listagem abaixo:
import { Component, Input, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-video',
template: `
{{data.counter}} {{count}}
<button (click)='senddata()'>send data</button>
<button (click)='sendcount()'>send count</button>
`
})
export class VideoComponent {
@Input() data: any;
@Input() count: number;
@Output() dataEvent = new EventEmitter();
@Output() countEvent = new EventEmitter();
senddata() {
this.dataEvent.emit(this.data);
}
sendcount() {
this.countEvent.emit(this.count);
}
}
Em ambos os eventos, estamos retornando as mesmas propriedades decoradas com @Input() para o componente pai. Em dataEvent, os dados são passados de volta e, em countEvent, count é passado de volta para o componente pai.
No componente pai, estamos capturando o evento conforme abaixo:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-video [data]='data' [count]='count' (dataEvent)='updateData($event)' (countEvent)='updateCount($event)' ></app-video>
`
})
export class AppComponent implements OnInit {
data: any = {};
count: number;
constructor() {
}
ngOnInit() {
this.data.counter = 1;
this.count = 1;
}
updateData(d) {
d.counter = d.counter + 1;
console.log(this.data.counter);
}
updateCount(c) {
c = c + 1;
console.log(this.count);
}
}
Vamos falar sobre updateData e updateCount função. Essas funções estão capturando eventos gerados no componente filho.
Na função updateData, estamos incrementando o valor do parâmetro passado, porém, por se tratar de um objeto, ele atualizará o valor de this.data e no componente filho, o valor atualizado será renderizado.
Na função updateCount, estamos incrementando o valor do parâmetro passado, porém, por ser do tipo primitivo, não atualizará this.count e no componente filho, nenhum impacto acontecerá.
Como saída ao clicar no botão, você verá que o valor dos dados está aumentando, mas o valor da contagem não está aumentando.
Podemos resumir que, se passarmos objetos no decorador @Input(), ele será passado como referência, e se passarmos tipos primitivos, será passado como valor. Espero que você ache este artigo útil. Obrigado por ler.
Se você gostou deste post, por favor, compartilhe-o. Além disso, se você não tiver feito check-outInfragistics Ignite UI for Angular Componentes, certifique-se de fazê-lo! Eles têm 30+ componentes de Angular baseados em materiais para ajudá-lo a codificar aplicativos da web mais rapidamente.
