13
respostas

Comunicação entre os valores de componente/modulos

Professor,

Estou fazendo uma POC do angular, uma simples página de checkout, e tenho o seguinte modulo estruturado.

product-shop-cart(component/module)

-> product-shop-cart-quantity (component) => Quantidade no array de produtos

-> product-shop-cart-itens (component/module) -> product-shop-cart-item(component) => Array dos produtos

-> product-shop-cart-total(component) => Valor total do carrinho

-> product-shop-cart-finalize(component) => Finalização do carrinho

Minha dificuldade no momento e pegar as informações dos componentes, o product-shop-cart(component/module) tem o seletor da quantidade que precisa ver a quantidade do array de produtos em product-shop-cart-itens (component/module).. assim a mesma coisa com o valor total do carrinho...

Files... product-shop-cart

<bml-product-shop-cart-quantity [quantity]="itens.length"></bml-product-shop-cart-quantity>
<bml-product-shop-cart-itens></bml-product-shop-cart-itens>
<bml-product-shop-cart-total></bml-product-shop-cart-total>
<bml-product-shop-cart-finalize"></bml-product-shop-cart-finalize>

product-shop-cart-itens

<div *ngFor='let item of itens'>
  <bml-product-shop-cart-item 
    [id]="item['id']"
    [description]="item['description']"
    [price]="item['price']"
  >
  </bml-product-shop-cart-item>
</div>

Ou seja gostaria de entender como pegar a quantidade de produto do outro módulo e valor total dos produtos do outro módulo?

Uma outra segunda dúvida que vai surgir é nessa mesma página eu tenho uma listagem de produtos... e gostaria de passar esse produto clicado para o outro modulo/componente que é justamente o shopping cart que um resumo que mostra ao lado na mesma página...

Atenciosamente,

13 respostas

.........

Bom dia. Você já assistiu o curso de fundamentos até o fim? Estou achando que não, pois eu ensino comunicação entre componentes com Output properties quando você cria o SearchComponent. Só aplicar o mesmo conceito, mas ainda precisará de mais conhecimento.

Aliás você está ainda no primeiro curso de Angular? Se sim, sugiro fazer todos os 4 cursos primeiro antes de crise sua aplicação pois há mais conceitos de comunicação entre componentes e técnicas com o framework que você não aprendeu .

Depois de assistir tente resolver essa questão que você postou. Se não conseguir, crie um novo post com a dúvida.

Mais uma coisa, em nenhum momento está recebendo como input property o array de itens. Está muito confuso para mim, pois você fez binding no componente anterior e nesse não. Talvez seja interessante rever essa parte. Mas em suma, a comunicação entre componentes é feita via Input (pai para filho), Ouput (filho para pai) e ViewChild ou ViewChildren, variável de template (irmão para irmão). Também pode ser feita por serviços. Tudo isso você vê passando por todos os cursos.

Sucesso e bom estudo.

Certo professor vou continuar aqui... qualquer coisa falo... Obrigado!

Vou adiantar alguns conceitos para que você fique antenado quando vê-los nos curso. Tudo bem?

Temos o seguinte componente filho que faz parte do template de um componente pai:

<componente-filho [itens]="itens" (selecionouItem)="metodoDoPai($event)">
</componente-filho>

Com esse exemplo, o componente pai passa a lista de itens para o componente filho através de uma inbound property, no caso [itens]. Porém, se internamente o filho lista vários itens, como o componente pai tem acesso ao item selecionado? Isso é feito através de uma Output propertie que é sempre um custom event. Veja:

<!-- $event é o item selecionado -->
(selecionouItem)="metodoDoPai($event)"

O component-filho tem um evento customizado chamado selecionouItem. Quando um item é selecionado lá dentro dele, ele dispara esse evento passando como valor o item selecionado. Então, (selecionouItem)="metodoDoPai($event)". Esse $event é o valor emitido pelo elemento filho. Veja que dessa maneira, um método do elemento pai será chamado recebendo essa informação, no caso, o item selecionado,.

Em suma, quando você for estudar o assunto, lembre-se que Output (@Output) properties é feita para realizar a comunicação entre elementos pai e filho e que Inbound properties (@Input).

Agora, podemos fazer uma comunicação de filho para filho. Veja o exemplo:

<!-- criou uma variável de template que dá acesso ao componente em qualquer lugar do template, inclusive suas propriedades e métodos -->
<componente-filho #componentItens [itens]="itens" (selecionouItem)="metodoDoPai($event)">
</componente-filho>

<component-total [total]="componentsItens.sum()">
</component-total>

Veja o [total]="componentsItens.sum()". Estamos chamando o método sum() de component-filho que esta sendo acessado através da variável de template componentItens.

Em suma, esse é um preview do que você aprenderá continuando os cursos de Angular. Os detalhes de implementação eu omitido, mas dei uma ideia geral de como você poderá organizar seu código.

Certo, professor muito obrigado pela esclarecimento... mas sabe como é nosso sangue só tem tranquilidade quando consegue..

Mas vendo os materiais na net e revendo os videos... é uma comunicação direta entre pai e filho e filho e pai.. ainda não consegui encaixar a minha situação em seu exemplo no vídeo..

Pode ajudar como seria este rascunho...

o componente "principal" e modulo => product-shop-cart, esse cara importa quatro seletores ...

  • product-shop-cart-quantity(receber um som emetido -> product-shop-cart-itens, quantidade de produtos no array)
  • product-shop-cart-itens (emitir o som a quantidade de produtos no array e fazer o @input para o filho product-shop-cart-item(já funcionando))
  • product-shop-cart-total(receber o som emitido -> product-shop-cart-itens, o valor total dos produtos no array))

Todos eles estão na mesma hierarquia, tudo dentro de product-shop-cart.

Files: product-shop-cart.component.html

<bml-product-shop-cart-quantity></bml-product-shop-cart-quantity>
<bml-product-shop-cart-itens></bml-product-shop-cart-itens>
<bml-product-shop-cart-total></bml-product-shop-cart-total>
<bml-product-shop-cart-finalize></bml-product-shop-cart-finalize>

product-shop-cart-itens.component.ts

import { Component, OnInit, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'bml-product-shop-cart-itens',
  templateUrl: './product-shop-cart-itens.component.html',
  styleUrls: ['./product-shop-cart-itens.component.css']
})
export class ProductShopCartItensComponent implements OnInit {

  @Output() quantity = new EventEmitter();
  @Output() purchase = new EventEmitter();

  total:number = 0;

  itens: any[] = [
    {
      "id": "001",
      "description": "Douglas  Pace",
      "price":"90"
    },
    {
      "id": "002",
      "description": "Mcleod  Mueller",
      "price":"90"
    },
    {
      "id": "003",
      "description": "Day  Meyers",
      "price":"90"
    }
  ];

  constructor() {}

  ngOnInit() {
    this.totalQuantity();
    this.totalPurchase();
  }

  totalQuantity(){

    this.quantity.emit(this.itens.length);

  }

  totalPurchase(){

    this.itens.forEach(item => {
      this.total = this.total + item.price;
    });

    this.purchase.emit(this.total);

  }

}

product-shop-cart-quantity.component.html

<h4 class="d-flex justify-content-between align-items-center mb-3">
    <span class="text-muted">Carrinho de Compra</span>
    <span class="badge badge-secondary badge-pill">{{ quantity }}</span>
</h4>

product-shop-cart-quantity.component.ts

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'bml-product-shop-cart-quantity',
  templateUrl: './product-shop-cart-quantity.component.html',
  styleUrls: ['./product-shop-cart-quantity.component.css']
})
export class ProductShopCartQuantityComponent implements OnInit{

  @Input() quantity = 0

  ngOnInit(){
  }

}

Eu acho que estou conseguindo enviar o som, meu problema de entendimento é para pegar esse som emitido pelo product-shop-cart-itens.component.ts..

Mas o curso eu vou continuar... minha ideia e fazendo algo diferente do que vc fez para aplicar o conhecimento e não somente colando do que foi feito..

Se puder me ajudar serei muito grato.

Atenciosamente,

Você chegou a terminar o terceiro curso ? Pelo o que eu vi foi até o primeiro. É importante para que eu não repita tudo que tem nesses vídeos. Acho louvável tentar aplicar o que aprendeu, mas só com o curso de fundamentos acho difícil você conseguir resolver seu problema.

Não ainda estou somente o primeiro curso.. mas vou avançar nesse mundo angular..

Mas a minha ideia no post de cima está no caminho certo... vc conseguiu entender?

Não sei se compreendi bem pelo design dos seu componentes (não entendi o termo som que você usou .. o que é esse tal som. Pelo o que eu vi só há dados, nenhum arquivo de som. ?

A respeito do componente ProductShopCartItensComponent, não vejo sentido eles utilizarem Output properties para disponibilizar a quantidade e o total, mas entendo que isso seja pelo fato de você ter feito apenas o curso de fundamentos do Angular e não ter avançado. Você aprenderá a trabalhar com variáveis de template e como elas podem te ajudar na comunicação no quarto curso de angular. Através de variáveis de template você pode acessar métodos e propriedades do componente no próprio template e pode passá-los para inbound propertires de outros compone antes. No post anterior passei um preview para você de como seria o uso e quando você chegar na aula específica aprenderá passo a passo como utilizá-lo.

Aliás, você tentou modelar a solução primeiro sem realizar essas divisões entre componentes? Quando você faz isso, pode até eliminar componentes desnecessários na hora de separar as coisas.

Sucesso e bom estudo.

O termo o som, foi confundido com o emitir evento(vamos entender emitir som é igual a emitir evento) para o outro componente "escutar/receber" o som ou evento emitido "Mas isso é um termo meu, para o entendimento".

O componente ProductShopCartItensComponent por ter o array de produtos pensei que ele fosse o responsável pelo Output(até onde eu entendi) ele vai emitir o evento de quantos produtos tem no carrinho e o valor total do carrinho...

no meu cenário acima quero que o componente product-shop-cart-quantity.component.ts possa receber essa informação e atualizar o template -> product-shop-cart-quantity.component.html.

Todos os seletores estão importados no componente product-shop-cart.

Consegui melhorar alguma coisa na explicação?

Atenciosamente,

Entendi sim. Só um ponto, é sobre essa declaração:

O componente ProductShopCartItensComponent por ter o array de produtos pensei que ele fosse o responsável pelo Output(até onde eu entendi) ele vai emitir o evento de quantos produtos tem no carrinho e o valor total do carrinho...

Eu entendo porque pensou assim, porque o conhecimento adquirido apenas com o curso de fundamentos não abre espaço para outras soluções mais apropriadas que são explicadas ao longo dos quatro cursos de Angular. Não há necessidade de emitir evento, você pode acessar o componente e passar o valor de qualquer propriedade como inbound property de outro, algo que você não aprendeu por ter feito apenas o curso de fundamentos. Se não me engano, em algum post pra cima eu dei um preview de como seria para você ter uma ideia e quando aprender nos cursos estar mais focado nesse recurso.

Fala Pessoal! Beleza?

Realmente, só com o conhecimento do curso de fundamentos você não terá uma solução adequada para o seu problema. Talvez seja interessante você terminar a formação angular até para se sentir mais seguro na solução de problemas como esse. Por agora, pode ser interessante fechar esse post e quando terminar os cursos e se a dúvida persistir, criar um novo post, pois esse tem muita informação que se repete!

Só uma sugestão, pois ficará mais fácil para alguém tirar sua dúvida.

É frustante não ser respondido pelo alura..

Muito Obrigado!