What is the correct way to communicate a component that is not a parent / child?

0

Good afternoon you will see very little developed in angular and I liked the framework very much, but I do not know if what I'm doing is the correct way to communicate my components or I'm committing a sacrilege of the good practices of angular. p>

You will see my application is based on a point of sale where in my main shopping cart section I have a structure as follows

Now the flow of the application can completely vary the component sale.linea is the parent of sidebar.component and of the element component

During flow I will have 1 or several different elements, depending on where I access to sale-linea.component but the sidebar will always be the same throughout the flow and should contain the data that was selected in all the components.

Each element component is subscribed to a service that makes a http request different from a server, and it responds with an object that of type ElementoVL several components will obtain this type of element but with different data or it may also obtain another object type or a combination of ElementoVL + OtroObjeto

I have my service object which makes an http request and it brings an object of type ElementoVL (eye the element VL I keep it in the own service and I do not return it since the goal is to keep the different ElementoVL that it obtains of different requests until the end of the purchase section so if the item returned it would be destroyed when the item changed.)

import { Injectable, DoCheck } from '@angular/core';
import { Http } from '@angular/http'
import 'rxjs/add/operator/map'
import {ElementoVL} from './ElementoVL'

@Injectable()
export class VentaLineaService implements DoCheck{
  elementoVL : ElementoVL [] = [];

  URL_INTERNET_20 : string = "http://localhost:8080/VL/internet";

  constructor( private http:Http) { }
  ngDoCheck(){
    for(var item  of this.elementoVL){
       console.log(item.nombreSiebel+"   "+item.selected)
     }
  }
  getInternet20 (){
    return this.http.get(this.URL_INTERNET_20)
            .map( res => {
                  this.elementoVL = res.json().servicios_internet;
                  console.log(this.elementoVL);
             })
  }

}

My component element.component (it is not called like that but I put the name of the element because there are several some work similarly, others do not) if they realize this works with the ElementoVL of the service where it saves the data in some variables (these variables are only used to present it in the HTML) however the selected variable of the ElementVL object of the service is modified.

import { Component, OnInit, DoCheck } from '@angular/core';
import { VentaLineaService } from '../../../services/venta-linea.service'
import {ElementoVL} from '../../../services/ElementoVL'

@Component({
  selector: 'app-internet20',
  templateUrl: './internet20.component.html',
  styleUrls: ['./internet20.component.css'],
})
export class Internet20Component implements OnInit,DoCheck {
  descripcion : String;
  precioSeleccionado : number = 0;
  element : ElementoVL;

  constructor(private ventaLineaService : VentaLineaService) {
  }

  ngOnInit() {
    this.ventaLineaService.getInternet20()
          .subscribe();

  }
  ngDoCheck(){
    if(this.descripcion === undefined){
    for(var item of this.ventaLineaService.elementoVL){
        if(item.selected)
        this.descripcion = item.descripcionExtendida;
      }
    }
  }

  cambiaInfo(item : ElementoVL){
      this.descripcion = item.descripcionExtendida;
      this.precioSeleccionado = item.precio;
      this.element = item;
        for(var itemAux of this.ventaLineaService.elementoVL){
          if(itemAux.id === item.id){
            itemAux.selected = true;
          }
          else{
            itemAux.selected = false;
         }
     }
   }
}

Now my sidebar where I am not subscribing to the request made by the element.component I am simply getting the ElementoVL of the service

import { Component, DoCheck } from '@angular/core';
import {ElementoVL} from '../../../../services/ElementoVL'
import { VentaLineaService } from '../../../../services/venta-linea.service'

@Component({
  selector: 'app-side-bar',
  templateUrl: './side-bar.component.html',
  styleUrls: ['./side-bar.component.css'],
})
export class SideBarComponent implements DoCheck {
  element : ElementoVL[];
  constructor(private ventaLineaService : VentaLineaService) { }

  ngDoCheck() {
   this.element =this.ventaLineaService.elementoVL
   for(let elem of this.element){
      console.log(elem.nombreSiebel +""+ elem.selected);
    }
  }
}

So far the application works I get the data in the element component and present the user can select any of the options I present depending on the data obtained and later when you select the value of the selected field of the element Vl changes to true so as the sidebar has this element detects the change by the DoCheck method and I can present the data that the user selected.

Now my question is, is this the correct way to pass information?

I ask why the flow will go through another element. component will keep the sidebar.component but the user can continue adding objects to the sidebar since it will continue to add them when they change their selected state to true and remove them when they go to false

    
asked by Polo 09.11.2017 в 23:29
source

1 answer

0

Eh answered something very similar a few weeks ago, look at the following:

Communication between components father-son

If there is not a relationship between the components you can pass parameters through the URL with the router service of angular

The form would be

app.module.ts

import { RouterModule, Routes } from '@angular/router';

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const appRoutes: Routes = [
  {
    path: 'componente2',
    component: Componente2Component
  }
];

export const routing = RouterModule.forRoot(appRoutes);

@NgModule({
  imports: [
    RouterModule.forRoot(
      appRoutes
    )
  ],
  exports: [
    RouterModule
  ],
})

export class AppRoutingModule { }

component1.component.ts

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

@Component({
    selector: 'app-componente1',
    templateUrl: './componente1.component.html'
})

export class Componente1Component implements OnInit {

  nombre: string = "";
  objeto: any = {};

  constructor(private router: Router) { }

  ngOnInit() {}

  navegarModelo = function () {

    //
    let parametros: any[] = [];
    this.parametros.push(this.nombre);
    this.parametros.push(this.objeto);

    this.router.navigate(['/componente2'], { queryParams: { array: parametros } });
  }
}
  

Step by url a collection of a string and an object

componente2.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from "@angular/router";

@Component({
    selector: 'app-componente2',
    templateUrl: './componente2.component.html'
})

export class Componente2Component implements OnInit {

  //
  nombreRecibido: string = "";
  objetoRecibido: any = {};

  constructor(
    private route: ActivatedRoute,
    private router: Router
  ) { }

  ngOnInit() {
    this.route.queryParams.subscribe((params: any) => {
      //Esta siguiente validación es para saber si me llegan parametros o no
      let detalleAux = JSON.stringify(params);
      if (let detalleAux.length > 2 && params.array[0] === "true") {
        this.nombreRecibido = params.array[1];
        this.objetoRecibido = params.array[2];
      }
    });
  }

}
    
answered by 10.11.2017 в 14:06