javascript - span - style html5
Datos de 4 pasos angulares entre 2 componentes no relacionados (3)
Este es un caso en el que desea utilizar un servicio compartido, ya que sus componentes están estructurados como hermanos y nietos. Aquí hay un ejemplo de un video. Creé un video sobre cómo compartir datos entre componentes que resuelve este problema exacto.
Comience creando un BehaviorSubject en el servicio
import { Injectable } from ''@angular/core'';
import { BehaviorSubject } from ''rxjs/BehaviorSubject'';
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject("default message");
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
Luego inyecte este servicio en cada componente y suscríbase al observable.
import { Component, OnInit } from ''@angular/core'';
import { DataService } from "../data.service";
@Component({
selector: ''app-parent'',
template: `
{{message}}
`,
styleUrls: [''./sibling.component.css'']
})
export class ParentComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
}
Puede cambiar el valor de cualquiera de los componentes y el valor se actualizará, incluso si no tiene la relación padre / hijo.
import { Component, OnInit } from ''@angular/core'';
import { DataService } from "../data.service";
@Component({
selector: ''app-sibling'',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: [''./sibling.component.css'']
})
export class SiblingComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
newMessage() {
this.data.changeMessage("Hello from Sibling")
}
}
Tengo una pregunta acerca de pasar datos en Angular.
Primero, no tengo una estructura como <parent><child [data]=parent.data></child></parent>
Mi estructura es
<container>
<navbar>
<summary></summary>
<child-summary><child-summary>
</navbar>
<content></content>
</container>
Entonces, en <summary />
tengo una selección que envía valor a <child-summary />
y <content />
.
El método OnSelect está bien activado con (cambiar) dentro del componente <summary />
.
Entonces, lo intenté con las @Input
, @Output
y @EventEmitter
, pero no veo cómo recuperar el evento como @Input del componente, a menos que continúe con el patrón padre / hijo. Todos los ejemplos que he fundado tienen una relación entre los componentes.
EDITAR: Ejemplo con BehaviorSubject que no funciona (todos los servicios conectados a la API funcionan bien, solo el observable se activa al inicio, pero no cuando la selección ha cambiado el valor)
servicio compartido = company.service.ts (utilizado para recuperar datos de la empresa)
import { Injectable } from ''@angular/core'';
import { Headers, Http, Response } from ''@angular/http'';
import { BehaviorSubject } from ''rxjs/BehaviorSubject'';
import { Observable } from ''rxjs/Observable'';
import ''rxjs/add/operator/toPromise'';
@Injectable()
export class SrvCompany {
private accountsNumber = new BehaviorSubject<string[]>([]);
currentAccountsNumber = this.accountsNumber.asObservable();
changeMessage(accountsNumber: string[]) {
this.accountsNumber.next(accountsNumber);
}
private _companyUrl = ''api/tiers/'';
constructor(private http: Http) { }
getSociete(): Promise<Response> {
let url = this._companyUrl;
return this.http.get(url).toPromise();
}
}
invoice.component.ts (el "hijo")
import { Component, OnInit, Input } from ''@angular/core'';
import { Headers, Http, Response } from ''@angular/http'';
import { SrvInvoice } from ''./invoice.service'';
import { SrvCompany } from ''../company/company.service'';
@Component({
selector: ''invoice'',
templateUrl: ''tsScripts/invoice/invoice.html'',
providers: [SrvInvoice, SrvCompany]
})
export class InvoiceComponent implements OnInit {
invoice: any;
constructor(private srvInvoice: SrvInvoice, private srvCompany: SrvCompany)
{
}
ngOnInit(): void {
//this.getInvoice("F001");
// Invoice data is linked to accounts number from company.
this.srvCompany.currentAccountsNumber.subscribe(accountsNumber => {
console.log(accountsNumber);
if (accountsNumber.length > 0) {
this.srvInvoice.getInvoice(accountsNumber).then(data => this.invoice = data.json());
}
});
}
//getInvoice(id: any) {
// this.srvInvoice.getInvoice(id).then(data => this.invoice = data.json());
//}
}
company.component.ts (el "padre")
import { Component, Inject, OnInit, Input } from ''@angular/core'';
import { Headers, Http, Response } from ''@angular/http'';
import { SrvCompany } from ''./company.service'';
@Component({
selector: ''company'',
templateUrl: ''tsScripts/company/company.html'',
providers: [SrvCompany]
})
export class CompanyComponent implements OnInit {
societes: any[];
soc: Response[]; // debug purpose
selectedSociete: any;
ville: any;
ref: any;
cp: any;
accountNumber: any[];
constructor(private srvSociete: SrvCompany)
{
}
ngOnInit(): void {
this.getSocietes();
}
getSocietes(): void {
this.srvSociete.getSociete()
.then(data => this.societes = data.json())
.then(data => this.selectItem(this.societes[0].Id));
}
selectItem(value: any) {
this.selectedSociete = this.societes.filter((item: any) => item.Id === value)[0];
this.cp = this.selectedSociete.CodePostal;
this.ville = this.selectedSociete.Ville;
this.ref = this.selectedSociete.Id;
this.accountNumber = this.selectedSociete.Accounts;
console.log(this.accountNumber);
this.srvSociete.changeMessage(this.accountNumber);
}
}
Hay dos soluciones para esto.
Esto se puede hacer a través del servicio compartido mediante el uso de observables.
Puedes usar ngrx / store para esto. Esto es similar al arco de Redux. Usted recibirá datos del estado.
Si el componente no está relacionado del que necesita, use el Servicio.
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service