2015-12-04 5 views
39

Ich habe Eckige Komponenten und erste Komponente verwendet die zweite als Direktive. Sie sollten das gleiche Modell Objekt teilen, die in der ersten Komponente initialisiert wird. Wie kann ich dieses Modell an die zweite Komponente übergeben?Wie überführe ich ein Objekt in Angular 2 von einer Komponente zur anderen?

+2

Können Sie etwas Code posten? Im Allgemeinen verwenden Sie Template-lokale Variablen für diese Art von Dingen in ng2, aber es ist schwer zu sagen, ohne ein bisschen mehr Details auf Ihrer Seite. – jlew

+0

Ich fand diese Antwort hilfreich: http://stackoverflow.com/a/31037168/1341825 – theUtherSide

Antwort

12

Komponente 2, die Direktivitätskomponente kann eine Eingabeeigenschaft definieren (@input Annotation in Typescript). Und Komponente 1 kann diese Eigenschaft an die Direktive-Komponente übergeben.

siehe SO diese How to do inter communication between a master and detail component in Angular2?

beantworten und wie wird eingegeben geordneten Komponenten weitergegeben werden. In Ihrem Fall ist es eine Richtlinie.

+0

Kann ich es für nicht Eltern-Kind-Komponenten verwenden? Zum Beispiel Und ich will alle Komponenten in Router-Steckdose haben einen Zugang zu Navbar-Komponente, ist es möglich? – EgorkZe

+1

@EgorkZe Um das zu erreichen, muss das Objekt, das Sie teilen, im gemeinsamen Elternteil dieser beiden Komponenten sein. Es gibt keine andere Möglichkeit, ein Objekt unter Geschwisterkomponenten zu teilen, was Sie beschrieben haben. –

34

für unidirektionale Datenbindung von Eltern auf Kinder, verwenden, um den @Input decorator (als recommended vom Style Guide) mit einem Eingang Eigenschaft auf der Kind-Bindungskomponente

@Input() model: any; // instead of any, specify your type 

und verwendet Vorlage Eigenschaft angeben, in der Eltern Vorlage

<child [model]="parentModel"></child> 

da Sie ein Objekt vorbei (ein JavaScript-Referenz-Typ) alle Änderungen, die Sie Objekte im übergeordneten Objekt oder das Kind Komponente in der anderen Komponente reflektiert werden, da b Beide Komponenten haben eine Referenz auf das gleiche Objekt. Ich zeige dies in der Plunker.

Wenn Sie neu zuweisen, das Objekt in der übergeordneten Komponente

this.model = someNewModel; 

Angular wird das neue Objekt Bezug auf die untergeordnete Komponente (automatisch als Teil der Änderungserkennung) propagieren.

Das einzige, was Sie nicht tun sollten, ist das Objekt in der untergeordneten Komponente neu zuzuweisen. Wenn Sie dies tun, wird das übergeordnete Objekt weiterhin auf das ursprüngliche Objekt verweisen. (Wenn Sie eine bidirektionale Datenbindung benötigen, siehe https://stackoverflow.com/a/34616530/215945).

@Component({ 
    selector: 'child', 
    template: `<h3>child</h3> 
    <div>{{model.prop1}}</div> 
    <button (click)="updateModel()">update model</button>` 
}) 
class Child { 
    @Input() model: any; // instead of any, specify your type 
    updateModel() { 
    this.model.prop1 += ' child'; 
    } 
} 

@Component({ 
    selector: 'my-app', 
    directives: [Child], 
    template: ` 
    <h3>Parent</h3> 
    <div>{{parentModel.prop1}}</div> 
    <button (click)="updateModel()">update model</button> 
    <child [model]="parentModel"></child>` 
}) 
export class AppComponent { 
    parentModel = { prop1: '1st prop', prop2: '2nd prop' }; 
    constructor() {} 
    updateModel() { this.parentModel.prop1 += ' parent'; } 
} 

Plunker - Angular RC.2

+0

du machst Gottes Arbeit! ein Hinweis für Geschwisterkomponenten? in meinem Fall habe ich 2 auf Root-Ebene Bootstrapped. HeaderComponent hat eine Sucheingabe, die ich mit Komponenten im Hauptteil teilen möchte. –

+0

@SonicSoul, setze die Daten in einen JavaScript-Referenztyp im Elternteil oder, wenn sie keinen Elternteil teilen, lege die Daten in einen gemeinsamen Bedienung. Für den Service-Ansatz können Sie erneut einen JavaScript-Referenztyp verwenden oder [Observables verwenden] (https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidrite-red-service). –

+0

danke! Ich versuche die Service-Route .. dachte nicht daran, tatsächlich die Observable darauf setzen –

2

Verwenden Sie die Ausgabe-Annotation

@Directive({ 
    selector: 'interval-dir', 
}) 
class IntervalDir { 
    @Output() everySecond = new EventEmitter(); 
    @Output('everyFiveSeconds') five5Secs = new EventEmitter(); 
    constructor() { 
    setInterval(() => this.everySecond.emit("event"), 1000); 
    setInterval(() => this.five5Secs.emit("event"), 5000); 
    } 
} 
@Component({ 
    selector: 'app', 
    template: ` 
    <interval-dir (everySecond)="everySecond()" (everyFiveSeconds)="everyFiveSeconds()"> 
    </interval-dir> 
    `, 
    directives: [IntervalDir] 
}) 
class App { 
    everySecond() { console.log('second'); } 
    everyFiveSeconds() { console.log('five seconds'); } 
} 
bootstrap(App); 
5

Sie Ihre Daten auch in einem Dienst mit einem Setter speichern könnte und es über einen Getter bekommen

import { Injectable } from '@angular/core'; 

@Injectable() 
export class StorageService { 

    public scope: Array<any> | boolean = false; 

    constructor() { 
    } 

    public getScope(): Array<any> | boolean { 
     return this.scope; 
    } 

    public setScope(scope: any): void { 
     this.scope = scope; 
    } 
} 
+0

Ihre Antwort ist zu kurz, aber es ist das richtige für keine Eltern-Kind-Komponenten. –

+0

Das ist eine großartige Idee. Ich bin so froh, dass ich diese Antwort gefunden habe. Es ist besonders gut, wenn Sie wissen, dass Ihr Objekt in vielen Komponenten auf der ganzen Seite ziemlich global verwendet wird. – Gherman