2016-02-15 8 views
5

Ich überlege, von meinem vertrauenswürdigen Rückgrat zu Angular2 zu bewegen (oder sollte ich sagen, mein Chef möchte mit einem neuen Spielzeug spielen, was für mich in Ordnung ist), suchte ich viel online und habe einige Tests gemacht, aber ich kann die Antwort auf diese einfache Frage nicht finden:Angular2, halten Modelle synchronisieren zwischen Komponenten

Kann ich zwei Modelle synchron zwischen zwei Komponenten halten? Beispiel: Ich habe eine Liste von Benutzern in der Seitenleiste, die eine Komponente ist, und ein Formular, um diese Benutzer in meiner "Hauptseite" zu bearbeiten, die eine andere Komponente ist.

Die Sidebar ist dafür verantwortlich, dass ihre Sammlung angezeigt wird, und das Formular ist für das Abrufen des Modells verantwortlich. Wenn das Modell aktualisiert wird, möchte ich, dass die Änderungen in der Seitenleiste widergespiegelt werden, ohne den Server erneut zu durchlaufen.

Ich weiß, SpinJS tut dies und ich habe etwas im Backbone mit Ereignissen, um das gleiche zu erreichen (basierend auf Modellklasse und ID) gehackt, aber ich frage mich, ob Angular2 eine native Art der Handhabung hat? Wenn nicht, wie würde man diese Art von Verhalten implementieren?

Danke.

EDIT:

Ich habe meine Testdateien in diesem Plunker: http://plnkr.co/edit/jIdnu68ZDMDSFJkomN3Y

Zuerst wählen Sie einen Helden, und klicken Sie auf "Details anzeigen", wird dies eine http.get Anfrage an den In-Memory-Server machen hol den Helden.

Zweitens, klicken Sie auf "Give Sword", das wird eine Waffe zum ausgewählten Benutzer hinzufügen. Zu Testzwecken, anstatt den bereits geladenen Benutzer zu verwenden, fordere ich denselben unter Verwendung http.get wieder an.

Wenn ich den Namen im Textfeld ändere, wird der Name der zweiten Instanz nicht aktualisiert.

Sie müssen sich vorstellen, dass ich die aktuelle Instanz des Helden aus welchen Gründen auch immer nicht verwenden kann, ich möchte es erneut vom Server anfordern.

+0

Was meinen Sie mit "Wenn ich den Namen im Textfeld ändere, wird der Name der zweiten Instanz nicht aktualisiert.". Wo sollte es aktualisiert werden? Der "Besitzer" der Waffe? –

+0

Richtig, da es dieselbe Klasse und dieselbe ID ist, habe ich mich gefragt, ob es eine Möglichkeit gibt, sie synchron zu halten wie SpineJS. – Growiel

Antwort

0

Ich denke, dass der beste Weg, um dies zu tun ist, EventEmitter in einem gemeinsamen Dienst zu nutzen. Wenn eine Änderung durchgeführt wird, wird ein Ereignis am Ereignisemitter gesendet. Andere Teile der Anmeldung, die sich dagegen registriert haben, werden benachrichtigt.

Siehe diese Antwort:

1

Sie einen Dienst zwischen Komponenten gemeinsam nutzen können.

@Injectable() 
export class SharedService { 
    someField:string; 
} 

@Component({selector: 'parent-cmp', providers [SharedService], ...) 
export class ParentCmp { 
    constructor(private model:SharedServicee) { 
    } 
} 

@Component({selector: 'child-cmp', 
    // don't add it to providers here so it gets the same instance 
    // the parent got 
    /*providers [SharedService] */, ...) 
export class ChildCmp { 
    constructor(private model:SharedServicee) { 
    } 
} 

Wenn eine Komponente ein Feld in dem Dienst ändert, sind der andere Service, der sie auch in der anderen Komponente sichtbar.

Sie können Observable oder EventEmitter verwenden, um interessierte Parteien über Änderungen oder andere Ereignisse zu informieren.

+0

Danke für die Antwort! Ich benutze bereits einen geteilten Dienst, aber das Problem ist, dass wenn ich UserServicer.get (id), ich eine neue Instanz mit aktualisierten Daten vom Server zurückgeben ... Vielleicht ist die Lösung, alle meine bereits abgerufenen Benutzer zu verfolgen Gibt es die gleiche Instanz von bereits abgerufen? Ein bisschen wie jedes Modell als Singleton. Scheint so, als würde dies dazu führen, dass die Modelle nie Müll gesammelt werden. – Growiel

+0

Wenn Sie die Daten in den Shared Service, den Sie bereits haben, setzen, sollte dies kein Problem sein. Der gemeinsam genutzte Dienst kann den Cache verwalten, wenn Sie die zuvor abgerufenen Daten beibehalten möchten, um bei nachfolgenden Anforderungen schneller reagieren zu können. –

+0

Ich habe es gerade noch einmal versucht und das Ergebnis ist das gleiche: Die zweite http.get() erstellt eine separate Instanz des Modells und wenn eine aktualisiert wird, ist die zweite nicht. Vielleicht vermisse ich etwas. – Growiel

1

Sie können gemeinsam genutzte Dienste verwenden, um dasselbe Ereignis in verschiedenen Komponenten zu abonnieren. (Wenn Sie diesen Dienst beim Bootstrap bereitstellen, erhalten Sie in allen Komponenten dasselbe Objekt. Sehr wichtig!).

Wenn Sie http.get anrufen möchten nur einmal, und dann wiederholen nur diesen Anruf, sollten Sie verwenden:

private _subject = new ReplaySubject(1); 
constructor(public http: Http) { 
    this.http 
     .get("...").subscribe(this._subject); 
} 

Voll, Arbeitsbeispiel: https://plnkr.co/edit/G1mSXfpuYaIGXNwK5WKy?p=preview

Werfen Sie einen Blick auf Netzwerk Panel (Chrom), Ajax-Aufruf wird nur einmal ausgelöst.

Verwandte Themen