Ir para o conteúdo
Angular componentes: passar por referência ou passar por valor?

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().

4min read

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.

  1. Na propriedade data, passaremos um objeto.
  2. 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.

Solicite uma demonstração