Angular 2从嵌套的TreeView指令组件调用parent组件

时间:2017-06-30 10:30:15

标签: angular

我正在使用从Torgeir Helgevold's postthis Plunker借来的TreeView组件。当双击任何节点时,我尝试从TreeView调用parents方法,但它仅适用于顶级节点。这是我到目前为止所拥有的 父母成分

 @Component({
    selector: 'hierarchy-mgmt',
    template: ' <div class="accounts-container col col-lg-3 col-md-4 col-xs-12">
        <h2>Managed Accounts</h2>
              <tree-item-renderer [account]="commonNodeModel.rootNode"
                                  (editing)="editStart($event)">
              </tree-item-renderer>
    </div>
               ',
    providers: [TreeItemRendererComponent]
 })
 export class HierarchyMgmtComponent implements OnInit {    
    //... constructor and other code
    ngOnInit(): void {
            this.nodeService.getNodesForUser()
        .then((rootNode: CustomerNode) => {
            this.commonNodeModel.RootNode = rootNode;
            this.commonNodeModel.SelectedNode = rootNode;
            return this.nodeService.getNodeValidationDetails();
        })
        .then((nodeValidationDetails: NodeValidationDetails) => {
            this.commonNodeModel.NodeValidationDetails = nodeValidationDetails;
            this.hierarchyLoaded = true;
            console.log(this.commonUserModel.usersForSelectedNode);
        })
        .catch(
            Utils.callFailureWithResponseDataFunction((failureResponse: any, hasBeenDisplayedToUser: any) => {
                this.notifyService.notifyUserIfNecessary(hasBeenDisplayedToUser, "There was a problem initialising this page. Please contact Support");
            }));
    }
    editStart(node: CustomerNode) {
        this.commonNodeModel.EditingNode = node;
    }
   // ... other code
 }

TreeItemRenderer组件

@Component({
    selector: 'tree-item-renderer',
    template: `
        <div class="node">
            <span class="node-input" [ngClass]="getSelectedClass()" (dblclick)="edit(account)" (click)="spanSelected()"
                  title="{{account.name}}" [innerHtml]="account.name"></span>
            <input type="text" class="editField" [ngModel]="account.name" placeholder="Enter an Account Name">
            <ul class="node-list">
                <li *ngFor="let account of account.children">
                    <tree-item-renderer [account]="account"  (editing)="editStart($event)"></tree-item-renderer>
                </li>
            </ul>
        </div>
    `
})

export class TreeItemRendererComponent implements OnInit {

    @Output()
    editing: EventEmitter<any> = new EventEmitter<any>();

    edit(node: any) {
        this.editing.emit(node);
    }
    // ... other codes 
}

问题是子节点已指向 TreeItemRenderer 组件而指向 HierarchyMgmtComponent 。猜测 TreeItemRenderer 组件需要类似(编辑)=&#34; parents.editStart($ event)&#34; 的内容。任何人都可以帮忙。谢谢。

此外,我知道 HierarchyMgmtComponent 组件可以注入 TreeItemRenderer 组件,&#34;我已经尝试了它并且它正在工作&#34; ,但这不是我想要的。

1 个答案:

答案 0 :(得分:1)

如果要从层次结构中的任何级别调用parents方法,则必须在链中一直连接事件处理程序。

请参阅此plunker:plunker

要将节点作为其子节点的父节点连接,请使用与顶级节点相同的语法。在TreeView组件中,添加一个事件处理程序方法(childObserverMethod),并在TreeView类中添加一个方法处理程序,该处理程序发出与父项连接到的相同事件(this.myParentObserverMethod.emit(node)):

@Component ({
  selector: 'tree-view',
  directives: [TreeView],
  template: `
  <ul>
    <li *ngFor="#node of treeData" >
      <span (click)="myClickMethod($event, node)">{{node.name}}</span>
      <tree-view [treeData]="node.subnodes" (myParentObserverMethod)="childObserverMethod($event)"></tree-view>
    </li>
</ul>
  `
})
export class TreeView {
  @Input() treeData: [];

  @Output()
  myParentObserverMethod: EventEmitter<any> = new EventEmitter<any>();

    myClickMethod(event, node)
    {
      this.myParentObserverMethod.emit(node);
      console.log("child - " + node.name)
    }

    childObserverMethod(node)
    {
      this.myParentObserverMethod.emit(node);
    }
}

修改

您可以重复使用myClickMethod,而不是创建另一种方法,例如

@Component ({
  selector: 'tree-view',
  directives: [TreeView],
  template: `
  <ul>
    <li *ngFor="#node of treeData" >
      <span (click)="myClickMethod($event, node)">{{node.name}}</span>
      <tree-view [treeData]="node.subnodes" (myParentObserverMethod)="myClickMethod($event)"></tree-view>
    </li>
</ul>
  `
})
export class TreeView {
  @Input() treeData: [];

  @Output()
  myParentObserverMethod: EventEmitter<any> = new EventEmitter<any>();

    myClickMethod(event, node)
    {
      this.myParentObserverMethod.emit(node);
      console.log("child - " + node.name)
    }
}