import { Component, EventEmitter, Input, Inject, enableProdMode, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { WjGridModule}  from 'wijmo/wijmo.angular2.grid';
import { WjInputModule} from 'wijmo/wijmo.angular2.input';
import * as wjcCore from 'wijmo/wijmo';
import { MyGridModule} from './MyGrid';
// NOTE: if you add imports of another Wijmo Ng2 modules,
// don't forget to add imported Wijmo NgModule(s)
// to the @NgModule.imports array at the end of this file.

import { DataSvc } from './services/DataSvc';

'use strict';

// The application root component.
@Component({
    selector: 'app-cmp',
    templateUrl: 'app/app.html',
})
export class AppCmp {
    dataSvc: DataSvc;
    data: wijmo.collections.CollectionView; 
    myPropertyValue = "The value";
    selectionMode = 'Cell';
    columns = [
        {binding: "downloads", header: "Downloads", format: "n0"},
        {binding: "sales", header: "Sales", format: "n2"},
        {binding: "active", header: "Active"},
      ];
    constructor( @Inject(DataSvc) dataSvc: DataSvc) {
        this.dataSvc = dataSvc;
        this.data = new wjcCore.CollectionView(this.dataSvc.getData(100));
       
    }
}

@NgModule({
    imports: [WjInputModule, WjGridModule, MyGridModule, BrowserModule, FormsModule],
    declarations: [AppCmp],
    providers: [DataSvc],
    bootstrap: [AppCmp]
})
export class AppModule {
}

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
<!DOCTYPE html>
<html>
  <head>
    <title>Wijmo Angular2 sample</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="https://unpkg.com/core-js/client/shim.min.js"></script>

    <script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
    <script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
   
    <!-- 3.. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System.import('wijmo.css').catch(function(err){ console.error(err); });
      System.import('./app/app').catch(function(err){ console.error(err); });
    </script>
  </head>

  <!-- 3. Display the application -->
  <body>
    <app-cmp>Loading...</app-cmp>
  </body>
</html>
# Wijmo for Angular 2 sample with external Wijmo modules

This sample can be used as a base for creating examples
with Wijmo components for Angular 2.
All the Wijmo modules are immediately available for a usage without any
additional setup. Just add corresponding 'import' statements
to to the code file (app.ts). For example:  
// Import core (non-Ng2) FlexChart control  
import { FlexChart } from 'wijmo/wijmo.chart';  
// Import Chart NgModule  
import { WjChartModule } from 'wijmo/wijmo.angular2.chart';  

When importing Wijmo Ng2 NgModule(s), don't forget to add them
to the @NgModule.imports array at the end of the app.ts file.

## Switching between pre-release and Release Wijmo versions
The sample is set up to use the latest Wijmo Release bits
by default.  
You may easily switch to the latest pre-release bits by uncommenting
the other **wijmoUrl** variable declaration in the first lines of 
the systemjs.config.js file.

You may also change the Angular 2 version used by the sample
in the **ngVer** variable declaration in systemjs.config.js.
/**
 * PLUNKER VERSION
 * (based on systemjs.config.js in angular.io)
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
  // Ng2 version
  var ngVer = '2.4.1';
  
  /// Wijmo code URL, incomment one of the wijmoUrl var declarations.
  // uncomment to use the latest pre-release version
  var wijmoUrl = 'http://prerelease.componentone.com/wijmo5/';
  // uncomment to use the latest Release version
  //var wijmoUrl = 'http://cdn.wijmo.com/5.';
  
  var wijmoNpmImageUrl = wijmoUrl + 'latest-npm-images/wijmo-amd-min';
  var wijmoCssUrl = wijmoUrl + 'latest/styles/';
  
  
  System.config({
    // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
    transpiler: 'ts',
    typescriptOptions: {
      tsconfig: true
    },
    meta: {
      'typescript': {
        "exports": "ts"
      },
      '*.css': { loader: 'css' },
    },
    paths: {
      // paths serve as alias
      'npm:': 'https://unpkg.com/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      app: 'app',

      // angular bundles
      '@angular/core': 'npm:@angular/core@' + ngVer + '/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common@' + ngVer + '/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler@' + ngVer + '/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser@' + ngVer + '/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@' + ngVer + '/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http@' + ngVer + '/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router@' + ngVer + '/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms@' + ngVer + '/bundles/forms.umd.js',
      '@angular/upgrade': 'npm:@angular/upgrade@' + ngVer + '/bundles/upgrade.umd.js',

      // other libraries
      'rxjs':                      'npm:rxjs',
      'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
      'ts':                        'npm:plugin-typescript@4.0.10/lib/plugin.js',
      'typescript':                'npm:typescript@2.0.3/lib/typescript.js',
      
      // Wijmo
      'wijmo': wijmoNpmImageUrl,
      'wijmo.css': wijmoCssUrl + 'wijmo.min.css',
      
      'css': 'https://unpkg.com/systemjs-plugin-css/css.js'

    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        defaultExtension: 'ts'
      },
      rxjs: {
        defaultExtension: 'js'
      },
      wijmo: {
          defaultExtension: 'js',
          // we need this to work around cross-origin issue on cdn.wijmo.com
          meta: {
            '*': {'scriptLoad': true}
          }
      }
    }
  });
})(this);


/*
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
*/
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "../../node_modules/@types/"
    ]
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules/*",
    "**/*-aot.ts"
  ]
}
'use strict';

import { Injectable } from '@angular/core';

// Common data service
@Injectable()
export class DataSvc {
    private _products = ['Widget', 'Gadget', 'Doohickey'];
    private _colors = ['Black', 'White', 'Red', 'Green', 'Blue'];
    private _musicians = 'Paul,Mark,Pete,Ringo,Luke,Jacob,John,Nate,Zym,George,Toom,Crash,Boom,Dewd'.split(',');
    private _someCountries = ['US', 'Germany', 'UK', 'Japan', 'Italy', 'Greece'];
    private _allCountries = [
        'Afghanistan', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antigua', 'Argentina', 'Armenia',
        'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize',
        'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bonaire', 'Bosnia', 'Botswana', 'Brazil', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burundi',
        'Cambodia', 'Cameroon', 'Canada', 'Canary Islands', 'Cape Verde', 'Cayman Islands', 'Central African Republic', 'Chad', 'Channel Islands',
        'Chile', 'China', 'Christmas Island', 'Cocos Island', 'Colombia', 'Comoros', 'Congo', 'Cook Islands', 'Costa Rica', "Cote D'Ivoire",
        'Croatia', 'Cuba', 'Curacao', 'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'East Timor', 'Ecuador',
        'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Falkland Islands', 'Faroe Islands', 'Fiji', 'Finland',
        'France', 'French Guiana', 'French Polynesia', 'French Southern Ter', 'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar',
        'Great Britain', 'Greece', 'Greenland', 'Grenada', 'Guadeloupe', 'Guam', 'Guatemala', 'Guinea', 'Guyana', 'Haiti', 'Honduras',
        'Hong Kong', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Isle of Man', 'Israel', 'Italy', 'Jamaica', 'Japan',
        'Jordan', 'Kazakhstan', 'Kenya', 'Kiribati', 'Korea North', 'Korea South', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', 'Lebanon', 'Lesotho',
        'Liberia', 'Libya', 'Liechtenstein', 'Lithuania', 'Luxembourg', 'Macau', 'Macedonia', 'Madagascar', 'Malaysia', 'Malawi', 'Maldives',
        'Mali', 'Malta', 'Marshall Islands', 'Martinique', 'Mauritania', 'Mauritius', 'Mayotte', 'Mexico', 'Midway Islands', 'Moldova', 'Monaco',
        'Mongolia', 'Montserrat', 'Morocco', 'Mozambique', 'Myanmar', 'Nambia', 'Nauru', 'Nepal', 'Netherland Antilles', 'Netherlands', 'Nevis',
        'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', 'Norway', 'Oman', 'Pakistan', 'Palau Island',
        'Palestine', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Pitcairn Island', 'Poland', 'Portugal', 'Puerto Rico',
        'Qatar', 'Republic of Montenegro', 'Republic of Serbia', 'Reunion', 'Romania', 'Russia', 'Rwanda', 'St Barthelemy', 'St Eustatius',
        'St Helena', 'St Kitts-Nevis', 'St Lucia', 'St Maarten', 'Saipan', 'Samoa', 'San Marino', 'Saudi Arabia', 'Scotland', 'Senegal', 'Serbia',
        'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'Spain', 'Sri Lanka',
        'Sudan', 'Suriname', 'Swaziland', 'Sweden', 'Switzerland', 'Syria', 'Tahiti', 'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', 'Togo',
        'Tokelau', 'Tonga', 'Trinidad Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks & Caicos Is', 'Tuvalu', 'Uganda', 'Ukraine',
        'United Arab Emirates', 'United Kingdom', 'United States of America', 'Uruguay', 'Uzbekistan', 'Vanuatu', 'Vatican City State',
        'Venezuela', 'Vietnam', 'Virgin Islands (British)', 'Virgin Islands (USA)', 'Wake Island', 'Yemen', 'Zaire', 'Zambia', 'Zimbabwe'
    ];

    // data used to generate random items
    getData(count: number, allCountries: boolean = false): any[] {
        var countries = allCountries ? this._allCountries : this._someCountries,
            data = [];
            for (var i = 0; i < count; i++) {
                data.push({
                    id: i,
                    country: countries[Math.round(Math.random() * (countries.length - 1))],
                    date: new Date(2014, i % 12, i % 28),
                    downloads: Math.round(Math.random() * 10000),
                    sales: +(Math.random() * 10000).toFixed(2),
                    active: i % 4 == 0
                });
            }
            return data;
    }

    getSomeCountries(): string[] {
        return this._someCountries;
    }

    getAllCountries(): string[] {
        return this._allCountries;
    }

    getProducts(): string[] {
        return this._products;
    }

    getColors(): string[] {
        return this._colors;
    }

    getMusicians(): string[] {
        return this._musicians;
    }

    getTreeData(): [{}] {
        return [
            {
                name: '\u266B Adriane Simione', items: [
                    {
                        name: '\u266A Intelligible Sky', items: [
                            { name: 'Theories', length: '2:02' },
                            { name: 'Giant Eyes', length: '3:29' },
                            { name: 'Jovian Moons', length: '1:02' },
                            { name: 'Open Minds', length: '2:41' },
                            { name: 'Spacetronic Eyes', length: '3:41' }]
                    }
                ]
            },
            {
                name: '\u266B Amy Winehouse', items: [
                    {
                        name: '\u266A Back to Black', items: [
                            { name: 'Addicted', length: '1:34' },
                            { name: 'He Can Only Hold Her', length: '2:22' },
                            { name: 'Some Unholy War', length: '2:21' },
                            { name: 'Wake Up Alone', length: '3:43' },
                            { name: 'Tears Dry On Their Own', length: '1:25' }]
                    },
                    {
                        name: '\u266A Live in Paradiso', items: [
                            { name: "You Know That I'm No Good", length: '2:32' },
                            { name: 'Wake Up Alone', length: '1:04' },
                            { name: 'Valerie', length: '1:22' },
                            { name: 'Tears Dry On Their Own', length: '3:15' },
                            { name: 'Rehab', length: '3:40' }]
                    }]
            },
            {
                name: '\u266B Black Sabbath', items: [
                    {
                        name: '\u266A Heaven and Hell', items: [
                            { name: 'Neon Knights', length: '3:03' },
                            { name: 'Children of the Sea', length: '2:54' },
                            { name: 'Lady Evil', length: '1:43' },
                            { name: 'Heaven and Hell', length: '2:23' },
                            { name: 'Wishing Well', length: '3:22' },
                            { name: 'Die Young', length: '2:21' }]
                    },
                    {
                        name: '\u266A Never Say Die!', items: [
                            { name: 'Swinging The Chain', length: '4:32' },
                            { name: 'Breakout', length: '3:54' },
                            { name: 'Over To You', length: '2:43' },
                            { name: 'Air Dance', length: '1:34' },
                            { name: 'Johnny Blade', length: '1:02' },
                            { name: 'Never Say Die', length: '2:11' }]
                    },
                    {
                        name: '\u266A Paranoid', items: [
                            { name: 'Rat Salad', length: '3:44' },
                            { name: 'Hand Of Doom', length: '4:21' },
                            { name: 'Electric Funeral', length: '2:12' },
                            { name: 'Iron Man', length: '3:22' },
                            { name: 'War Pigs', length: '3:13' }]
                    }]
            },
            {
                name: '\u266B Brand X', items: [
                    {
                        name: '\u266A Unorthodox Behaviour', items: [
                            { name: 'Touch Wood', length: '2:54' },
                            { name: 'Running of Three', length: '1:34' },
                            { name: 'Unorthodox Behaviour', length: '2:23' },
                            { name: 'Smacks of Euphoric Hysteria', length: '3:12' },
                            { name: 'Euthanasia Waltz', length: '2:22' },
                            { name: 'Nuclear Burn', length: '4:01' }]
                    }]
            }
        ];
    }
}
<h3>This sample demonstrates a MyGrid custom component inherited from 
    WjFlexGrid, along with MyColumn custom component inherited from 
    WjFlexGridColumn</h3>
<p>
  The inherited component classes use special <b>wjFlexGridMeta</b> 
  and <b>wjFlexGridColumnMeta</b> variables exported from the grid module
  to define their @Component metadata. These variables store corresponding
  @Component property values that can be easily merged with definitions
  specific to derived components. The @Component metadata declared this way
  is compatible with Angular 2 ahead-of-time compiler. 
</p>
<p>
  Note that <b>wj-flex-grid-column</b> and 
  <b>[wjFlexGridCellTemplate]</b> can
  be used with the inherited <b>my-grid</b> component,
  and mixed with custom <b>my-column</b> components.
</p>
<p>
  Some of the columns are created dynamically using an ngFor directive 
  bound to a column definition array.
</p>
<my-grid [itemsSource]="data" [(myProperty)]="myPropertyValue" style="height:300px">
    <wj-flex-grid-column [header]="'Country'" [binding]="'country'" [width]="150">
    </wj-flex-grid-column>
    <my-column [header]="'Date (editor template)'" [binding]="'date'" [width]="170">
      <template [wjFlexGridCellTemplate] cellType="CellEdit" let-cell="cell">
        <wj-input-date [(value)]="cell.value" [isRequired]="false"></wj-input-date>
      </template>
    </my-column>
    <my-column *ngFor="let col of columns"  
        [header]="col.header" 
        [binding]="col.binding"
        [format]="col.format">
    </my-column>
</my-grid>
import { Component, Inject, Injector, NgModule, ElementRef,
    SkipSelf, Optional, forwardRef, ChangeDetectorRef,
    EventEmitter } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { WjValueAccessorFactory } from 'wijmo/wijmo.angular2.directiveBase';
import { WjGridModule, WjFlexGrid, wjFlexGridMeta, 
    WjFlexGridColumn, wjFlexGridColumnMeta }  from 'wijmo/wijmo.angular2.grid';


@Component({
    selector: 'my-grid',
    template: wjFlexGridMeta.template,
    inputs: [...wjFlexGridMeta.inputs, 'myProperty'],
    outputs: [...wjFlexGridMeta.outputs, 'myPropertyChange'],
    providers: [
        { provide: 'WjComponent', useExisting: forwardRef(() => MyGrid) },
        ...wjFlexGridMeta.providers
    ]
})
export class MyGrid extends WjFlexGrid {
  private _myProperty: string;
  myPropertyChange = new EventEmitter(false);

  get myProperty(): string {
      return this._myProperty;
  }
  set myProperty(value: string) {
      if (this._myProperty !== value) {
          this._myProperty = value;
          this.myPropertyChange.emit(value);
      }
  }
}


@Component({
    selector: 'my-column',
    template: wjFlexGridColumnMeta.template,
    inputs: wjFlexGridColumnMeta.inputs,
    outputs: wjFlexGridColumnMeta.outputs,
    providers: [
        { provide: 'WjComponent', useExisting: forwardRef(() => MyColumn) },
        ...wjFlexGridColumnMeta.providers
    ]
})
export class MyColumn extends WjFlexGridColumn {
}


@NgModule({
    imports: [WjGridModule, BrowserModule, FormsModule],
    declarations: [MyGrid, MyColumn],
    exports: [MyGrid, MyColumn]
})
export class MyGridModule {
}