2017-10-25 3 views
0

In Angular kann eine Komponente eine Variable oder ein Objekt als @Input() empfangen. Wann immer sich die Variable ändert, benachrichtigt Angular die Komponente. Sehr cool ...Kann ein Objekt benachrichtigt werden, wenn sich ein Komponentenobjekt in Angular 2/4 ändert?

Ich versuche, eine App zu erstellen, die eine ng2-tree Ansicht auf der linken Seite und eine Bearbeitungsansicht auf der rechten Seite zeigt. Wenn der Benutzer auf einen Knoten in der Struktur klickt, werden die Details dieses Elements auf der rechten Seite angezeigt, und der Benutzer kann die Eigenschaften dieses Elements ändern. Was ich brauche, ist, dass sich diese Änderungen zurück zum Baum ausbreiten.

Die einzelnen Knoten in dem Baum sind ein ItemTreeNode:

export class ItemTreeNode implements TreeModel { 
    value: string; 
    id: string; 
    children: Array<ItemTreeNode>; 
    icon: string; 
    settings: TreeModelSettings; 
    loadChildren; 

    constructor(
    private itemService: ItemService, 
    private parent_id: string, 
    public item: Item 
){ ... } 
} 

Der Baum macht den Knoten .value für den Namen verwendet wird. Dies wird während des Konstruktors durch Aufrufen von this.item.nodeName() festgelegt. Einmal eingestellt, ändert es sich nicht. Das Problem ist, es muss sich ändern, wenn der Artikel geändert wird.

Was ich suchen ist eine Möglichkeit für dieses Objekt benachrichtigt werden, wenn das Element ändert, so dass die value Eigenschaft aktualisiert werden kann.

Gibt es eine Möglichkeit für die ItemTreeNode, das Element zu "beobachten" und einen Rückruf zu erhalten, wenn es sich jemals ändert, als Teil des Änderungszyklus von Angular?

Oder gibt es eine bessere Möglichkeit, das gewünschte Verhalten zu implementieren?

+0

Ja, Sie können [Shared Services] (https://rahulrsingh09.github.io/AngularConcepts/faq) oder [Ngrx] (https://rahulrsingh09.github.io/AngularConcepts/ngrx) einsehen. –

Antwort

0

Dies könnte mit Hilfe von RxJs getan werden. Unterbrechen wir die Namenseinstellung des Elements über den Setter und triggert einen Observable .next().

import {BehaviorSubject} from 'rxjs/BehaviorSubject' 

class Item { 
    private _name: string; 
    private nameSource = new BehaviorSubject<string>(''); 
    name$ = this.nameSource.asObservable(); 

    set name(name: string) { 
    this._name = name; 
    this.nameSource.next(name); 
    } 

    get name() { return this._name; } 

    getNodeName() { return this._name + ' !!!'; } 

    constructor(name: string){ 
    this._name = name; 
    } 
} 

Sie sehen, ich schiebe den Namen des ursprünglichen Artikel auf this.nameSource.next(name). In meinem Beispiel nehme ich an, dass der Name des Elements und der Name des Knotens unterschiedlich sind. Observable $name ist öffentlich, es ist für externe Abonnements. Dann brauche ich auf Artikel Namensänderung zu abonnieren, und der beste Ort dafür ist der ItemTreeNode Konstruktor, der eine Item-Instanz als Parameter erhält:

class Node { 
    value: string; 

    constructor(item: Item) { 
    item.name$.subscribe(result => this.value = item.getNodeName()); 
    } 
} 

die hier result ist der neue Name des Artikels, aber da es nicht das ist Genau wie der Knotenname des Elements, mache ich einen zusätzlichen Anruf .getNodeName(). Das einzige, was Sie tun müssen, ist, die Instanz von Items an den Konstruktor von Node zu übergeben, und dann macht RxJs die Binde-Magie für Sie.

this.item = new Item('My Name'); 
const node = new Node(this.item); 

Das ist alles, creatred ich ein Plunker diesen Ansatz zu demonstrieren.

Verwandte Themen