Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No Controller for New Nodes Added via addChild #204

Closed
dpollastrini opened this issue Jan 31, 2018 · 7 comments
Closed

No Controller for New Nodes Added via addChild #204

dpollastrini opened this issue Jan 31, 2018 · 7 comments

Comments

@dpollastrini
Copy link

` updateCampaignScriptTreeModel(script: IScript): void {

let targetScriptNodeController: TreeController = this.scriptTreeComponent.getControllerByNodeId(script.id);

if (targetScriptNodeController) {

  let targetScriptTreeModel = targetScriptNodeController.toTreeModel();

  if (targetScriptTreeModel.title !== script.title) {
    targetScriptNodeController.rename(script.title);
  }
}
else {
  let targetParentScriptNodeController: TreeController = this.scriptTreeComponent.getControllerByNodeId(script.parentScriptId);

  if (!targetParentScriptNodeController) {
    targetParentScriptNodeController = this.scriptTreeComponent.rootComponent.controller;
  }

  targetParentScriptNodeController.addChild({ id: script.id, value: script.title, children: [] });
  targetParentScriptNodeController.expand();

  let addedScriptModelController: TreeController = this.scriptTreeComponent.getControllerByNodeId(script.id);
  addedScriptModelController.select();
}

}`

I'm dynamically updating a TreeModel based on an arbitrary data model object ("script" in the example above). When using "addChild" in the above, I note that the children are added to the correct parent TreeModel as expected and the added nodes appear correctly in my tree.

However, it seems no new TreeController is added to the TreeService.controllers collection as part of the addChild function (I have verified this in a debugger). Consequently, the subsequent call to get the "addedScriptModelController" returns a null. Per the code my intent in this case is to "select" the newly created node after it is added. Obviously, relying on the rest of the API also requires access to an existing node controller for newly "added" nodes.

Am I doing something wrong here, or are there design limitations that prevent controllers from being added as part of of the addChild function?

@dpollastrini
Copy link
Author

I found my problem. I needed to use "createNode" rather than passing an anonymous object directly in to addChild.

` ...
let newNode = this.scriptTreeComponent.tree.createNode(true, { id: script.id, value: script.title, children: [] });

  targetParentScriptNodeController.addChild(newNode);

...
`

@rychkog
Copy link
Contributor

rychkog commented Feb 5, 2018

@dpollastrini Thanks for sharing - this is a good case for the paragraph in the documentation.

@boban100janovski
Copy link

boban100janovski commented Feb 5, 2018

Hi guys, im having the same issue, but the code sample by @dpollastrini did not work form me.

tree-controller -> addChild already calls "createNode", but the problem is that id does not create a controller for the corresponding new node, as in if you initialize the component with a starting treeModel it loops trough all the nodes creates a tree-internal instance and also a controller.

public addChild(newNode: TreeModel): void {
    if (this.tree.hasDeferredChildren() && !this.tree.childrenWereLoaded()) {
      return;
    }

    const newTree = this.tree.createNode(Array.isArray(newNode.children), newNode);
    this.treeService.fireNodeCreated(newTree);
  }

So in my case given a starting multi level nested treeModel everything works great.

But if i try to create the same nested structure with "addChild" node programatically it will fail because the new nodes won't have controllers and hence you cannot add children nodes to those created before.

A sample tree model would be something like:
1
.... 1.1
........... 1.1.1
............ 1.1.2

@rychkog Have you managed to create such a structure using "addChild"?

Temporary solution:
So now im building the tree with a temp treeModel, and reassiging it to the treeModel that is bound so changes will get reflected.
But this way "toTreeModel()" returns only the initial state of the tree, so to get the treeModel after the user has added/removed or renamed some node i call this.treeComponent.tree.

Would just like to mention that i think the code of ng2-tree is very clean and nicely documented, the project has great potential and with a bit more work could be taken to new level.

@rychkog
Copy link
Contributor

rychkog commented Feb 6, 2018

@boban984 thanks, I'll reopen this and have a look.

@rychkog rychkog reopened this Feb 6, 2018
@rychkog rychkog added the bug label Feb 6, 2018
@rychkog
Copy link
Contributor

rychkog commented Feb 11, 2018

@dpollastrini @boban984 TreeController requires TreeInternalComponent in order to control its behavior. But I have an idea. I'll add a createChildAsync method to the controller, therefore allowing TreeInternalComponent to create a new controller for the child on one event loop iteration and resolving the new child on a subsequent one.

Here is how it will look like:

this.treeFFS.getControllerByNodeId(1)
  .addChildAsync({id: 'Boo!', value: 'Casper :)'})
    .then(casper => this.treeFFS.getControllerByNodeId('Boo!').select());

What do you think about this, will it resolve your issues?

@boban100janovski
Copy link

@rychkog that would be ideal

@rychkog
Copy link
Contributor

rychkog commented Feb 15, 2018

@boban984 Actually this functionality is already in master and released. I just haven't had enough time for updating the doc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants