2017-04-08 6 views
-1

Ja, das wurde ein paar Mal gefragt - fühlen Sie sich frei die Frage zu verschmelzen - aber ich bin wahrscheinlich ein lamer. Ich habe zwei Komponenten in einer Seite, der so gehen:Daten von einer eckigen Komponente zu einer anderen übergeben

<post-list></post-list> 
<post-detail><post-detail> 

Dies ist eine sehr einfache Master-Detail-Seite. Wenn der Benutzer auf ein Element in einer Liste in post-list klickt, lädt post-detail den ausgewählten Beitrag und zeigt ihn an.

Die Frage ist, wie bekomme ich einen Wert von post-list zu post-detail, um es sofort reagieren zu lassen? Ich nehme an, es sollte ein Observable in post-detail warten auf Änderungen sein. Ich nehme auch an, dass es eine Eingabeeigenschaft überwachen sollte. Die Frage ist: kann ich einen Wert von post-list bekommen und es als eine Eingabeeigenschaft an post-detail senden? Kann (und sollte) ich es durch die Elternkomponente leiten, oder soll ich einen Dienst dafür definieren?

+3

da Sie Erwähnen Observable, können wir annehmen, dass dies eine Frage über angular2 ist und nichts mit angularjs zu tun hat? – Claies

+0

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service – echonax

+0

Ja, Angular 2, genauer Angular 4. Danke für den Link. –

Antwort

2

Eine Möglichkeit zu tun ist von @Input und @Output Dekorateure. Ihre übergeordnete Komponente sollte damit umgehen, was an und von der untergeordneten Komponente übergeben wird.

<post-list 
    (itemSelected)="loadDetails(any)"> 
</post-list> 
<post-detail 
    [selectedItem]="any"> 
<post-detail> 

itemSelected -> ein Ausgang ist, der ein EventEmitter ist, die emittiert was aus der Liste Komponente an die übergeordnete Komponente ausgewählt wird.

loadDetails (beliebig) -> Dies ist eine Methode in Ihrer übergeordneten Komponente, die behandelt, was von der Liste Komponente emittiert wird, tun was erforderlich ist, was Sie von dem Kind erhalten.

selectedItem -> ist eine Eingabe-Eigenschaft im Detail Komponente und es könnte von jedem Typ sein, die idealerweise erhalten sollte, was von loadDetails strukturiert wird.

Dies ist nur eine einfache Vorlage, die Ihre Anforderung erfüllen könnte. Aber ein Dienst könnte geschrieben werden, um dies auch zu behandeln.

1

Da beide Komponenten über ein gemeinsames Elternelement verfügen, besteht die einfachste Möglichkeit darin, die @Input() - und @Output() -Eigenschaften zu verwenden und das übergeordnete Element die Rolle eines Mediators zu spielen. Ich habe ein kurzes Video dazu aufgenommen: https://www.youtube.com/watch?v=tSXx4NoKEYY

Sie können Master-Detail auch mit dem Router und Observable implementieren. Bloged hier darüber: https://yakovfain.com/2016/11/20/angular-2-implementing-master-detail-using-router/

0

Sie können dies wie folgt vor:

1- inject $ rootScope auf Ihre beiden Komponenten

2- Code unten zu einem von ihnen als Datenempfänger implementieren:

$rootScope.$on('transferDataEvent', function(data) { 

    }); 

3- und für einen anderen Anruf unter dem Code als Datensender

$rootScope.$emit('transferDataEvent', data); // send data 

$ auf machen einen Zuhörer und $ emittieren das Ereignis

nach oben durch den Umfang Hierarchie entsendet
+0

Das ist AngularJS, nicht Angular, aber trotzdem danke. Leider gibt es noch kein Angular 4-Tag für Fragen. –

1

Die Frage ist, wie bekomme ich einen Wert von post-Liste post-Detail, um es sofort zu machen reagieren ? Ich nehme an, dass im Nachhinein ein Observable auf Änderungen warten sollte. Ich nehme auch an, dass es eine Eingabeeigenschaft überwachen sollte. Die Frage ist: Kann ich einen Wert von der Post-Liste erhalten und es als eine Eingabe-Eigenschaft an Post-Detail senden? Kann (und sollte) ich es durch die Elternkomponente leiten, oder soll ich einen Dienst dafür definieren?

Diese Situation ist ziemlich einfach - die Post-Liste muss, um anzuzeigen, wenn ein Element ausgewählt ist, und das selectedItem 'passieren Informationen auf das Post-Detail für die Anzeige.

Wenn ich diese Situation behandle, würde ich einfache Eingaben und Ausgaben (d. H. Eigentums- und Ereignisbindungen) verwenden, um die Informationen zwischen den Komponenten zu übergeben, wobei die Elternkomponente als Vermittler der Kommunikation verwendet wird. Sie leiten es durch die Hauptkomponente - im Speziellen zeigt die Post-Liste an, wann ein Post ausgewählt ist und was dieser Post ist, während das Post-Detail einfach anzeigt, welcher Post ihm übergeben wird.

Also, die Post-Liste benötigt eine @Output EventEmitter-Eigenschaft namens itemSelect oder etwas anderes angemessen. Der Zweck dieser Eigenschaft besteht darin, jeden zu benachrichtigen, der sich dafür interessiert, wenn ein Element ausgewählt wird und um welches Element es sich handelt.

PostListComponent:

export class PostDetailComponent { 
    ..... 
    @Output() postSelect = new EventEmitter(); 

    // whenever a post is selected, you call this.postSelect.emit(selectedPost) 
    // to notify others which post is selected 

Im PostDetailComponent:

export class PostDetailComponent { 
    ..... 
    // this is your property binding 
    // used to get data in real time in to the component for display 
    @Input() post; 

Schließlich ist die übergeordnete Komponente einen Beitrag Eigenschaft benötigt, Updates von der Post-Liste zu erhalten und diese Aktualisierungen passieren zu das Post-Detail.

Parent

Die Parent einfach für Updates vom PostList hört, und sie auf Empfang, weist die Substanz des Ereignisses (der $ Ereigniswert in der Vorlage) in seine internen Post Eigenschaft, die wiederum wird an die PostDetails geschoben.

@Component({ 
    ....... 
    template: ` 
     <post-list (postSelect)="post = $event"> </post-list> 
     <post-detail [post]="post"> </post-detail> 
    ` 
}) 
export class ParentComponent { 
    post: any; // brokers the communication between the two child components 
    ....... 

So würde ich die Situation.

Sie können einen Dienst verwenden, um die Kommunikation zu vermitteln, aber das ist normalerweise nur erforderlich, wenn das Kommunikationsmittel kompliziert ist oder die beiden Komponenten in der Ansichtshierarchie nicht nah beieinander liegen. Daher ist es schwierig, Informationen von einem zu erhalten Komponente zum anderen. Aber in Ihrem Fall kann ein Service übertrieben sein.

See the docs for more info.

+0

Danke. Das war genau das, was mir vorschwebte und in der Zwischenzeit umgesetzt wurde. Ich war mir nicht sicher, ob dies nicht gegen eine bewährte Methode oder eine ungeschriebene Regel verstößt. Das ist das Schwierige an Angular, nicht die Logik dahinter. –

0

Ein einfacher Ansatz, um Ihr Problem ist Variablen Vorlage Referenz zu verwenden: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ref-vars

Ich schlage vor, dass, weil Ihre Komponenten Geschwister sind, dh. teilen Sie sich das gleiche Elternteil.

Sie post-list Komponente auf der Vorlage auf diese Weise verweisen können:

Blick auf diese plnkr ich ein: https://plnkr.co/edit/C7kjlaZItfn0sE12HNMO?p=preview

hier ist der Code:

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello {{name}}</h2> 
     <post-list #postList></post-list> 
     <post-detail [text]="postList?.chosen?.detail"></post-detail> 
    </div> 
    `, 
}) 
export class App { 
    name:string; 
    constructor() { 
    this.name = `Angular! v${VERSION.full}` 
    } 
} 


@Component({ 
    selector: 'post-detail', 
    template: ` 
    <div> 
     <h2>{{text}}</h2> 
    </div> 
    `, 
}) 
export class PostDetail { 
    @Input() text: string; 
    constructor() { 
    } 
} 


@Component({ 
    selector: 'post-list', 
    template: ` 
    <div> 
     <ul> 
     <li *ngFor="let post of posts; let i = index"> 
     <button (click)="chosen = posts[i]">{{post.title}}</button> 
     </li> 
     </ul> 
    </div> 
    `, 
}) 
export class PostList { 
    chosen: any; 
    posts: [] = 
    [ 
    { title:"post 1", detail:"post one detail" }, 
    { title:"post 2", detail:"post two detail" }, 
    { title:"post 3", detail:"post three detail" }, 
    ] 
    constructor() { 
    } 
} 
Verwandte Themen