2016-08-31 3 views
9

Basierend auf der docs von Angular 2 können Sie Daten mit dem @Input ganz einfach von einer Komponente zu einer anderen übertragen.Angular 2 @Input: Können Daten von einer Komponente an eine andere untergeordnete Routenkomponente übergeben werden?

So zum Beispiel kann ich die Eltern wie folgt festgelegt:

import { Component } from '@angular/core'; 
import { HEROES } from './hero'; 
@Component({ 
    selector: 'hero-parent', 
    template: ` 
    <h2>{{master}} controls {{heroes.length}} heroes</h2> 
    <hero-child *ngFor="let hero of heroes" 
     [hero]="hero" 
     [master]="master"> 
    </hero-child> 
    ` 
}) 
export class HeroParentComponent { 
    heroes = HEROES; 
    master: string = 'Master'; 
} 

Und die die Daten in der untergeordneten Komponente wie diese:

import { Component, Input } from '@angular/core'; 
import { Hero } from './hero'; 
@Component({ 
    selector: 'hero-child', 
    template: ` 
    <h3>{{hero.name}} says:</h3> 
    <p>I, {{hero.name}}, am at your service, {{masterName}}.</p> 
    ` 
}) 
export class HeroChildComponent { 
    @Input() hero: Hero; 
    @Input('master') masterName: string; 
} 

So ist es ganz offensichtlich, die [hero]="data" passieren zu die Vorlage der Elternkomponente (natürlich in der Kindselektor) und behandeln sie in die Kindkomponente.

Aber hier ist das Problem.

Mein Kind Komponente DOM-Element (in diesem Fall <hero-child>) ist in der Eltern-Vorlage nicht verfügbar, sondern wird geladen dort in einem <router-outlet> Elemente.

Wie kann ich dann Daten an eine untergeordnete Route Komponente dann? Ist die Eingabe nicht der richtige Weg? Ich möchte doppelte, hohe usw. Anrufe vermeiden, um dieselben Daten zu erhalten, die bereits in meiner Elternroute/Komponente vorhanden sind.

+0

Ich würde ein modellgesteuertes Formular und einen Dienst anstelle der Vorlage verwenden – cport1

+2

Ich bekomme die Daten bereits über einen Dienst an die Eltern. Isn t das was du meinst? –

+2

@ cport1 wie modellgetriebene Form könnte helfen, er wollte Komponentendaten weitergeben, um 'HeroParentComponent' Daten an' HeroChildComponent' Daten zu übergeben, die in 'Router-outlet' liegen, Gute Frage :) –

Antwort

0

Erwägen Sie, einen Angular2-Dienst für @Input() oder @Output() zu erstellen, der mehr als eine Ebene oder eine nicht verwandte Komponente durchlaufen wird.

3

Ich glaube nicht, dass es eine Möglichkeit gibt, Objekte als Eingabe an eine Komponente zu übergeben, an die geroutet wird. Ich habe dies erreicht, indem ich einen Service mit einer Observable verwendet habe, um die Daten zwischen einem Elternteil und einer oder mehreren Kindkomponenten zu teilen.

Grundsätzlich ruft die übergeordnete Komponente den Dienst auf und schiebt alle erforderlichen Daten dorthin. In meinem Fall ist es nur eine ID, aber es könnte alles sein. Der Service kann dann etwas mit diesen Daten machen (oder nicht). In meinem Beispiel rufe ich den Server an, um eine Firma basierend auf der ID zu erhalten, aber wenn Sie bereits das Objekt haben, das Sie brauchen, wird dieses nicht benötigt. Dann schiebt es ein Objekt in einen Observable-Stream, der in der Kindkomponente abonniert ist.

Geordnete Komponente:

import { Component, OnInit, OnDestroy } from '@angular/core'; 
import { ActivatedRoute, Params } from '@angular/router'; 
import { SalesProcessService } from './salesProcess.service'; 
import { Subscription } from 'rxjs/Rx'; 

@Component({ 
    selector: 'ex-sales-process', 
    template: ` 
     <router-outlet></router-outlet> 
    ` 
}) 
export class SalesProcessComponent implements OnInit, OnDestroy { 
    private companyRowId: string; 
    private paramsSubscription: Subscription; 
    constructor(
     private salesProcessService: SalesProcessService, 
     private route: ActivatedRoute 
    ) {} 
    ngOnInit() { 
     this.paramsSubscription = this.route.params.subscribe((params: Params) => { 
      if (this.companyRowId !== params['companyId']) { 
       this.companyRowId = params['companyId']; 
       this.salesProcessService.getCompany(this.companyRowId); 
      } 
     }); 
    } 
    ngOnDestroy() { 
     this.paramsSubscription.unsubscribe(); 
    } 

} 

Service:

import { Injectable } from '@angular/core'; 
import { CompanyDataService } from '../common/services/data'; 
import { ReplaySubject } from 'rxjs'; 
import { Observable, Subject, Subscription } from 'rxjs/Rx'; 

@Injectable() 
export class SalesProcessService { 
    private companyLoadedSource = new ReplaySubject<any>(1); 
    /* tslint:disable:member-ordering */ 
    companyLoaded$ = this.companyLoadedSource.asObservable(); 
    /* tslint:enable:member-ordering */ 

    constructor (
     private companyDataService: CompanyDataService) { } 
    getCompany(companyRowId: string) { 
     // Data service that makes http call and returns Observable 
     this.companyDataService.getCompany(companyRowId).subscribe(company => this.companyLoadedSource.next(company)); 
    } 

} 

Kinder Komponente

import { Component, OnInit, OnDestroy } from '@angular/core'; 
import { SalesProcessService } from '../salesProcess.service'; 
import { Subscription } from 'rxjs/Rx'; 

@Component({ 
    selector: 'ex-company', 
    template: require('./company.component.html'), 
    styles: [require('./company.component.css')] 
}) 
export class CompanyComponent implements OnInit, OnDestroy { 
    company: any; 
    private companySub: Subscription; 
    constructor(
     private salesProcessService: SalesProcessService 
     ) { } 
    ngOnInit() { 
     this.companySub = this.salesProcessService.companyLoaded$.subscribe(company => { 
      this.company = company; 
     }); 
    } 
    ngOnDestroy() { 
     this.companySub.unsubscribe(); 
    } 
} 
0

können Sie erreichen, was Sie wollen von:

  • Erstellen eines Dienstes, der einen Status für Sie enthält. Die untergeordnete Komponente kann später darauf zugreifen.
  • Übergabe der Daten über den Router (dynamische Route, queryParam, param). Beispiel: users /: id => users/23
  • Übergabe der Daten mithilfe einer Bibliothek für die Statusverwaltung. ZB: Redux
Verwandte Themen