In Blogs, Techblog, Workspace

Within “Workspace”, a product which facilitates an easy way to use groups and teams with a clear overview, the functionality to tag a group or a team has been added . Tagged groups/teams can be used to quickly find the desired workspace in a large set of groups/teams through filtering. A tag tree was created, where each tag can have child tags, these child tags can have children of their own and so on. Some of the challenges to overcome implementing this feature were how to use unlimited nesting in a template and how to make sure all the functionality works in such a tree. Examples of solutions to tackle these challenges are presented in this blog.

Nesting template

To create the tree the “Angular UI Tree”   (https://github.com/angular-ui-tree/angular-ui-tree) component was used. Because the nesting of the tags is unlimited, a simple iteration through the parent tags and its child tags in the template is not viable. An example of a nested template can be found below. Make sure that you use the ng-include both inside and outside the script and watch the quotes. Furthermore, make sure that the same iteration word is used in both ng-repeats, in this case “workspaceTag”.

<script type="text/ng-template" id="workspaceTagTree"> <div ui-tree-handle> {{workspaceTag.label }} </div> <ol ui-tree-nodes="" ng-model="node.nodes"> <li ng-repeat="workspaceTag in workspaceTag.children" ui-tree-node ng-include="'workspaceTagTree'"> </li> </ol> </script> <div ui-tree> <ol ui-tree-nodes="" ng-model="data" id="tree-root"> <li ng-repeat="workspaceTag in workspaceTags" ui-tree-node ng-include="'workspaceTagTree'"></li> </ol> </div>

Nesting functions

An admin page is created in which an admin is able to add tags, add child tags, add children of child tags and so on. The tags can also be deleted, merged with each other and the tags can be rearranged. To create all this functionality in this tag tree recursive functions were used.

An example of the deletion of a tag in the tree is given below. Notice that to locate the desired tag to be deleted an iteration through all the elements in the tree is required. The recursive “deleteTagInTree” function is called with the array of elements which have no parents and the id of the tag to be deleted as parameters. If the element is not found in the first array an iteration through the children of the elements in the array is done by calling the same function repeatedly with the children of the element as a parameter. If the element is found it is deleted, furthermore all of its children are collected through the recursive “getNestedChildren” function and are also deleted. In the “getNestedChildren” function an iteration through all elements in the array and its children is performed. All desired elements are put in a seperate array, which is returned.

deleteTagInTree(arr: Array<WorkspaceTag>, id: string) { for (var i in arr) { if (arr[i].id === id) { // delete the element from storage this.tableStorageService.deleteWorkspaceItem(arr[i].tenantId, arr[i].id, 'tag'); // check if the element has children if (arr[i].children) { // get all children recursively let allChildren = this.getNestedChildren(arr[i].children); // delete all children and grandchildren and so on from storage allChildren.forEach(child => { this.tableStorageService.deleteWorkspaceItem(arr[i].tenantId, child.id, 'tag'); }); } // delete the item from the array arr.splice(arr.findIndex(a => a === arr[i]), 1); } else { // element is not found. Keep looking in the children if (arr[i].children) { this.deleteTagInTree(arr[i].children, id); } } } } getNestedChildren(arr: Array<WorkspaceTag>) { var out = []; for (var i in arr) { if (arr[i].children) { var children = this.getNestedChildren(arr[i].children); out.push(arr[i]); out.push.apply(out, children); } else { out.push(arr[i]); } } return out; }

Vul je zoekopdracht in.

blocks margins and paddings