<!DOCTYPE html>
<html>

  <head>
    <title>Angular Plunker Template</title>
    <!-- Load common libraries -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.11/zone.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.14/system.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/web-animations/2.2.2/web-animations.min.js"></script>
    <!-- Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System
        .import('main.ts')
        .catch(console.error.bind(console));
    </script>
    <style>body { font-family: Roboto, Arial, sans-serif; margin: 0 }</style>
  </head>

  <body class="mat-app-background">
    <angular-app>Loading the Angular App...</angular-app>
    <!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->
  </body>

</html>
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import { FormsModule } from '@angular/forms'
import {HttpModule} from '@angular/http';
import { NgxTreeModule } from 'ngx-tree'
import {AppComponent} from './app.component';

@NgModule({

  imports: [
    BrowserModule,
    CommonModule,
    FormsModule,
    HttpModule,
    BrowserAnimationsModule,
    NgxTreeModule,
  ],

  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: []
})
export class PlunkerAppModule {}

platformBrowserDynamic().bootstrapModule(PlunkerAppModule);

/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Use of this source code is governed by an MIT-style license that
 can be found in the LICENSE file at http://angular.io/license
 */
/** Add Transpiler for Typescript */
const typescriptVersion = '2.3.4';
const angularVersion = '4.4.6';
System.config({
  transpiler: 'ts',
  typescriptOptions: {
    tsconfig: true
  },
  meta: {
    'typescript': {
      "exports": "ts"
    }
  },
  packages: {
    '.': {
      defaultExtension: 'ts'
    },
    'ngx-tree': {
      defaultExtension: 'ts',
      main: "index",
    },
    // Thirdparty barrels.
    'rxjs': { main: 'index' },
  },
  map: {
    'main': 'main.js',
    
    // Angular specific mappings.
    '@angular/core': `https://unpkg.com/@angular/core@${angularVersion}/bundles/core.umd.js`,
    '@angular/common': `https://unpkg.com/@angular/common@${angularVersion}/bundles/common.umd.js`,
    '@angular/compiler': `https://unpkg.com/@angular/compiler@${angularVersion}/bundles/compiler.umd.js`,
    '@angular/animations': `https://unpkg.com/@angular/animations@${angularVersion}/bundles/animations.umd.js`,
    '@angular/animations/browser': `https://unpkg.com/@angular/animations@${angularVersion}/bundles/animations-browser.umd.js`,
    '@angular/http': `https://unpkg.com/@angular/http@${angularVersion}/bundles/http.umd.js`,
    '@angular/forms': `https://unpkg.com/@angular/forms@${angularVersion}/bundles/forms.umd.js`,
    '@angular/router': `https://unpkg.com/@angular/router@${angularVersion}/bundles/router.umd.js`,
    '@angular/platform-browser': `https://unpkg.com/@angular/platform-browser@${angularVersion}/bundles/platform-browser.umd.js`,
    '@angular/platform-browser/animations': `https://unpkg.com/@angular/platform-browser@${angularVersion}/bundles/platform-browser-animations.umd.js`,
    '@angular/platform-browser-dynamic': `https://unpkg.com/@angular/platform-browser-dynamic@${angularVersion}/bundles/platform-browser-dynamic.umd.js`,
    '@angular/material': `https://rawgit.com/angular/material2-builds/master/bundles/material.umd.js`,
    '@angular/cdk': `https://rawgit.com/angular/cdk-builds/master/bundles/cdk.umd.js`,

    
    // Third party libraries
    'ts': 'https://npmcdn.com/plugin-typescript', // transpiler, use latest
    'typescript': 'https://npmcdn.com/typescript@' + typescriptVersion + '/lib/typescript.js',
    'tslib': 'https://unpkg.com/tslib@1.7.1',
    'rxjs': 'https://unpkg.com/rxjs@5.5.10',
    'lodash': 'https://unpkg.com/lodash@4.17.0',
    'element-closest': 'https://unpkg.com/element-closest',
    
    // Custom libraries
    'ngx-tree': 'https://rawgit.com/e-cloud/ngx-tree/virtual-scroll-demo-branch/src/lib',
  }
});

/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Use of this source code is governed by an MIT-style license that
 can be found in the LICENSE file at http://angular.io/license
 */
import {Component} from '@angular/core';
import {generateData} from './generate-data'
import { TreeOptions } from 'ngx-tree/models/tree-options.model'

@Component({
  selector: 'angular-app',
  templateUrl: 'app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
    title = 'demo'

    nodes: any[]

    asyncChildren = [
        {
            name: 'child2.1',
            subTitle: 'new and improved',
        },
        {
            name: 'child2.2',
            subTitle: 'new and improved2',
        },
    ]

    customTemplateStringOptions = new TreeOptions({
        // displayField: 'subTitle',
        isExpandedField: 'expanded',
        idField: 'uuid',
        getChildren: this.getChildren.bind(this),
    })

    constructor() {
        this.nodes = generateData()
    }

    getChildren(node: any) {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve(this.asyncChildren.map((c) => {
                return Object.assign({}, c, {
                    hasChildren: node.level < 5,
                })
            })), 1000)
        })
    }

    log($event) {
        // console.log($event)
    }
}
<ngx-tree
  [nodes]="nodes"
  [options]="customTemplateStringOptions"
  (expand)="log($event)"
  (collapse)="log($event)"
  (changeFilter)="log($event)"
  (toggleExpander)="log($event)"
  (addNode)="log($event)"
  (removeNode)="log($event)"
  (activate)="log($event)"
  (deactivate)="log($event)"
  (focus)="log($event)"
  (blur)="log($event)"
  (initialized)="log($event)"
  (loadChildren)="log($event)"
></ngx-tree>
export function generateData() {
  const nodes = [
      {
          expanded: true,
          name: 'root expanded 1',
          subTitle: 'the root',
          children: [
              {
                  name: 'child1',
                  subTitle: 'a good child',
                  hasChildren: false,
              },
              {
                  name: 'child2',
                  subTitle: 'a bad child',
                  hasChildren: false,
              },
          ],
      },
      {
          expanded: true,
          name: 'root expanded 2',
          subTitle: 'the root',
          children: [
              {
                  name: 'child1',
                  subTitle: 'a good child',
                  hasChildren: false,
              },
              {
                  name: 'child2',
                  subTitle: 'a bad child',
                  hasChildren: false,
              },
          ],
      },
      {
          name: 'asyncroot',
          hasChildren: true,
      },
      {
          expanded: true,
          name: 'root2',
          subTitle: 'the second root',
          children: [
              {
                  name: 'child2.1',
                  subTitle: 'new and improved',
                  uuid: '11',
                  hasChildren: false,
              },
              {
                  expanded: true,
                  name: 'child2.2',
                  subTitle: 'new and improved2',
                  children: [
                      {
                          uuid: 1001,
                          name: 'subsub',
                          subTitle: 'subsub',
                          hasChildren: false,
                      },
                      {
                          expanded: true,
                          name: 'root 3',
                          subTitle: 'the second root',
                          children: [
                              {
                                  name: 'child2.1',
                                  subTitle: 'new and improved',
                                  uuid: '11',
                                  hasChildren: false,
                              },
                              {
                                  expanded: true,
                                  name: 'child2.2',
                                  subTitle: 'new and improved2',
                                  children: [
                                      {
                                          uuid: 1001,
                                          name: 'subsub',
                                          subTitle: 'subsub',
                                          hasChildren: false,
                                      },
                                  ],
                              },
                          ],
                      },
                      {
                          expanded: true,
                          name: 'root 4',
                          subTitle: 'the second root',
                          children: [
                              {
                                  name: 'child2.1',
                                  subTitle: 'new and improved',
                                  uuid: '11',
                                  hasChildren: false,
                              },
                              {
                                  expanded: true,
                                  name: 'child2.2',
                                  subTitle: 'new and improved2',
                                  children: [
                                      {
                                          uuid: 1001,
                                          name: 'subsub',
                                          subTitle: 'subsub',
                                          hasChildren: false,
                                      },
                                  ],
                              },
                          ],
                      },
                  ],
              },
          ],
      },
  ]

  for (let i = 0; i < 4; i++) {
      nodes.push({
          expanded: i === 0,
          name: `root Dynamic${i}`,
          subTitle: `root created dynamically ${i}`,
          children: new Array((i + 1) * 100).fill(null).map((item, n) => ({
              name: `child Dynamic${i}.${n}`,
              subTitle: `child created dynamically ${i}`,
              hasChildren: false,
          })),
      })
  }
  
  return nodes
}
ngx-tree {
  display: block;
  margin-top: 250px;
  height: 400px;
  width: 300px;
  outline: 1px solid grey;
}
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  }
}