0

在 Angular 中,组件可以作为@Input()变量或对象接收。每当变量发生变化时,Angular 都会通知组件。很酷...

我正在尝试构建一个ng2-tree在左侧显示视图和在右侧显示编辑视图的应用程序。当用户单击树中的一个节点时,该项目的详细信息将显示在右侧,用户可以更改该项目的属性。我需要的是让这些更改传播回树。

树中的各个节点是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
  ){ ... }
}

树呈现.value用于名称的节点。这是在构造函数期间通过调用设置的this.item.nodeName()。一旦设置,它就不会改变。问题是,每当更改项目时,它都需要更改。

我正在寻找的是一种在项目更改时通知此对象的方法,以便value可以更新属性。

ItemTreeNode作为 Angular 更改检测周期的一部分, 有没有办法“监视”该项目并在它发生变化时接收回调?

还是有更好的方法来实现所需的行为?

4

1 回答 1

0

这可以在 RxJs 的帮助下完成。让我们通过 setter 中断 Item 的名称设置并触发 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;
  }
}

你看,我将原始项目的名称推送到this.nameSource.next(name). 在我的示例中,我假设项目的名称和节点的名称是不同的。Observable$name是公开的,用于外部订阅。然后我需要订阅 Item 的名称更改,最好的地方是 ItemTreeNode 构造函数,它获取一个 Item 实例作为参数:

class Node {
  value: string;

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

这里result是 Item 的新名称,但由于它与 Item 的节点名称不同,所以我做了一个额外的 call .getNodeName()。所以你唯一需要做的就是将 Item 的实例传递给 Node 的构造函数,然后 RxJs 为你做绑定魔法。

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

就是这样,我创建了一个Plunker来演示这种方法。

于 2017-10-25T19:42:07.623 回答