1

I am using TreeView Component borrowed from Torgeir Helgevold's post or this Plunker. I try to call parents method from TreeView when is double click on any node but it works only for top node. Here is what I have so far Parents Component

 @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

@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 
}

The problem is that child node has referent to TreeItemRenderer component and not to HierarchyMgmtComponent. Guess in TreeItemRenderer component needs something like (editing)="parents.editStart($event)". Can anyone help please. Thank you.

In addition, I am aware of that HierarchyMgmtComponent component can be injected into TreeItemRenderer component, "which I have tried it and it is working", but it is not what I am looking for.

1

1 Answer 1

1

If you want to call the parents method from any level down within the hierarchy, you will have to wire up event handlers all the way down the chain.

See this plunker: plunker

To wire up the nodes as a parent to their children, use the same syntax as you did for the top level. In the TreeView component, add an event handler method (childObserverMethod) and in the TreeView class, add a method handler that emits the same event as the parent is wired to (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);
    }
}

Edit:

You could re-use the myClickMethod rather than create another method, e.g.

@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)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.