扁平数组构建DOM树

interface IOrganizationNode {
        id: string;
        code: string;
        name: string;
        localName: string;
        localNameLocale: string;
        parentCode: string;
        description: string;
        children?: IOrganizationNode[];
    }
    interface IOrganizationTree {
        organizationTree: IOrganizationNode[];
    }

interface IOrganization {
    id: string;
    code: string;
    name: string;
    localName: string;
    localNameLocale: string;
    parentCode: string;
    description: string;
}

    export class OrganizationTree {
        public static GenerateOrganizationsDom: string = "GenerateOrganizationsDom" + _gcEditingInput;

        public static createTreeDom(array: IOrganization[]): HTMLElement {
            let DOMObject: HTMLElement = document.createElement("div");
            DOMObject.className = "select-user-tree-container";
            let organizationTree: IOrganizationTree = OrganizationTree.CreateTreeData(array);
            DOMObject.appendChild(OrganizationTree.CreateTreeDom(organizationTree.organizationTree, true));
            this._bindEvent(DOMObject);
            return DOMObject;

        }

        private static CreateTreeData(array: IOrganization[]): IOrganizationTree {
            let r: IOrganizationNode[] = [];
            let codeToOrganizationMap: Dictionary<IOrganization> = {};
            let len = array.length;
            let orgs: IOrganization[] = [];
            //deep copy
            for (let i = 0; i < len; i++) {
                let org: any = {};
                for (var attr in array[i]) {
                    org[attr] = array[i][attr];
                }
                orgs.push(org);
            }
            for (let i = 0; i < len; i++) {
                codeToOrganizationMap[orgs[i].code] = orgs[i];
            }
            for (let j = 0; j < len; j++) {
                let org: IOrganizationNode = orgs[j];
                let parentOrg: IOrganizationNode = codeToOrganizationMap[org.parentCode];

if (parentOrg) {
if (parentOrg.children) {
parentOrg.children.push(org);
} else {
parentOrg.children = [];
parentOrg.children.push(org);
}
} else {
r.push(org);
}


            }
            let result: any = {};
            result.organizationTree = r;
            return result;
        }

        private static CreateTreeDom(treeNodes: IOrganizationNode[], top?: boolean): HTMLElement {
            let ul = document.createElement("ul") as HTMLUListElement;
            if (top) {
                ul.classList.add("tree");
                ul.classList.add("tree-root");
                //ul.classList.add("tree", "tree-root");//chrome unsupport
            } else {
                ul.classList.add("tree");
            }
            for (let i = 0; i < treeNodes.length; i++) {
                let li = document.createElement("li") as HTMLLIElement;
                li.classList.add("tree-node");
                let a = document.createElement("a") as HTMLAnchorElement;
                a.classList.add("tree-node-label");
                let spanName = document.createElement("span") as HTMLSpanElement;
                spanName.classList.add("tree-node-name");
                spanName.innerText = treeNodes[i].name;
                spanName["GCSK_OrganizationCode"] = treeNodes[i].code;
                let spanArrow = document.createElement("span") as HTMLSpanElement;
                spanArrow.classList.add("tree-node-arrow");
                a.appendChild(spanName);
                a.appendChild(spanArrow);
                li.appendChild(a);

                if (treeNodes[i].children) {
                    li.classList.add("tree-node-haschildren");
                    li.appendChild(OrganizationTree.CreateTreeDom(treeNodes[i].children));
                }
                ul.appendChild(li);
            }
            return ul;
        }

        private static _bindEvent(DOMObject: HTMLElement) {
            let self = this;
            GC$(DOMObject).bind("click", (event) => {
                let srcElement = <HTMLElement>(event.srcElement || event.target);
                if (srcElement.classList.contains("tree-node-name")) {
                    let liElement = srcElement.parentElement.parentElement;
                    // first remove all <li> classname
                    Array.prototype.forEach.call(DOMObject.querySelectorAll(".tree-node"), item => { item.classList.remove("tree-node-selected"); });
                    //then add current <li> 
                    if (liElement.classList.contains("tree-node-haschildren")) {
                        liElement.classList.add("tree-node-opened");
                    }
                    liElement.classList.add("tree-node-selected");

                    var evt = document.createEvent("UIEvent") as UIEvent;
                    evt.initEvent(OrganizationTree.GenerateOrganizationsDom, true, false);
                    evt["GCSK_OrganizationCode"] = srcElement["GCSK_OrganizationCode"];
                    liElement.dispatchEvent(evt);

                } else if (srcElement.classList.contains("tree-node-arrow")) {
                    let liElement = srcElement.parentElement.parentElement;
                    if (srcElement.parentElement.parentElement.classList.contains("tree-node-opened")) {
                        liElement.classList.remove("tree-node-opened");
                    } else {
                        liElement.classList.add("tree-node-opened");
                    }
                }
            });
        }
    }
原文地址:https://www.cnblogs.com/Yogurshine/p/7147076.html