<!DOCTYPE html>
<html>

  <head>
    <title>Angular 2</title>
    <script src="https://npmcdn.com/core-js/client/shim.min.js"></script>
    <script src="https://npmcdn.com/zone.js@0.6.12?main=browser"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.27/system.js"></script>
    <script src="https://npmcdn.com/typescript@1.8.10/lib/typescript.js"></script>
    <script src="systemjs.config.js"></script>

    <script>
      System.import('app').catch(function(err){ console.error(err);  });
    </script>
  </head>

  <body>
    <demo-app>Loading...</demo-app>
  </body>
</html>
import { Component } from '@angular/core';

@Component({
  selector: 'demo-app',
  templateUrl: 'app/app.component.html',
  pipes: []
})
export class AppComponent {
  constructor() { 
    this.counter = false;
    this.responseMock = [
      [
        {id: 1, name: 'Josh'},
        {id: 2, name: 'Joseph'},
        {id: 3, name: 'Kevin'}
      ],
      [
        {id: 1, name: 'Michael'},
        {id: 2, name: 'Frank'},
        {id: 3, name: 'Lian'}
      ]  
    ];
    

    var itemsMock = this.getItems();
    this.items = itemsMock;
    this.itemsTrackBy = itemsMock;

    var self = this;
    setInterval(function() {
      var itemsMock = self.getItems();
      self.items = itemsMock;
      self.itemsTrackBy = itemsMock;
    }, 5000);
  }

  getItems() {

    if (this.counter === false) {
      this.counter = true;
      return this.responseMock[0];
    }
    this.counter = false;
    return this.responseMock[1];
  }

  personIdentity( index, item ) {
    console.log( "TrackBy:", item.item, "at index", index );
    return( item.id );
  }

}

<h1>Angular 2 ngFor demo</h1>

<p>If you like to take a look in this implementation using Angular 1, please <a href="http://embed.plnkr.co/vIZP3U/">Take a look in this example</a></p>
<p>This is the Angular2 example with ngFor with track by.</p>
<p>Make sure that you are using track by in your app because we have the same behaviour that we had in Angular1.</p>
<p>Take a look in the examples.</p>
<h2>With track by</h2>
<ul>
  <li *ngFor="let itemTrackBy of itemsTrackBy; trackBy:personIdentity">
    {{itemTrackBy.id}} | {{itemTrackBy.name}}
  </li>
</ul>
<h2>Without trackBy</h2>
<p>Without `ngForTrackBy` the element is removed into DOM.</p>
<p>If you are not passing trackBy, your component will be removed into the DOM and rendered again.</p>
<ul>
  <li *ngFor="let item of items">
    {{item.id}} | {{item.name}}
  </li>
</ul>

/**
 * PLUNKER VERSION (based on systemjs.config.js in angular.io)
 * System configuration for Angular 2 samples
 * Adjust as necessary for your application needs.
 * Override at the last minute with global.filterSystemConfig (as plunkers do)
 */
(function(global) {
  //map tells the System loader where to look for things
  var  map = {
    'app':                               'app',
    'rxjs':                              'https://npmcdn.com/rxjs@5.0.0-beta.6',
    '@angular/common':                   'https://npmcdn.com/@angular/common@2.0.0-rc.5',
    '@angular/compiler':                 'https://npmcdn.com/@angular/compiler@2.0.0-rc.5',
    '@angular/core':                     'https://npmcdn.com/@angular/core@2.0.0-rc.5',
    '@angular/http':                     'https://npmcdn.com/@angular/http@2.0.0-rc.5',
    '@angular/platform-browser':         'https://npmcdn.com/@angular/platform-browser@2.0.0-rc.5',
    '@angular/platform-browser-dynamic': 'https://npmcdn.com/@angular/platform-browser-dynamic@2.0.0-rc.5',
    '@angular/router':                   'https://npmcdn.com/@angular/router@3.0.0-rc.1',
    '@angular/forms':                    'https://npmcdn.com/@angular/forms@0.3.0'
  };

  //packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                               { main: 'main.ts',  defaultExtension: 'ts' },
    'rxjs':                              { defaultExtension: 'js' },
    '@angular/common':                   { main: 'index.js', defaultExtension: 'js' },
    '@angular/compiler':                 { main: 'index.js', defaultExtension: 'js' },
    '@angular/core':                     { main: 'index.js', defaultExtension: 'js' },
    '@angular/http':                     { main: 'index.js', defaultExtension: 'js' },
    '@angular/platform-browser':         { main: 'index.js', defaultExtension: 'js' },
    '@angular/platform-browser-dynamic': { main: 'index.js', defaultExtension: 'js' },
    '@angular/router':                   { main: 'index.js', defaultExtension: 'js' },
    '@angular/router-deprecated':        { main: 'index.js', defaultExtension: 'js' },
    '@angular/upgrade':                  { main: 'index.js', defaultExtension: 'js' },
    '@angular/forms':                    { main: 'index.js', defaultExtension: 'js' }
  };

  var config = {
    transpiler: 'typescript',
    typescriptOptions: {
      emitDecoratorMetadata: true
    },
    map: map,
    packages: packages
  }

  // filterSystemConfig - index.html's chance to modify config before we register it.
  if (global.filterSystemConfig) { global.filterSystemConfig(config); }

  System.config(config);
})(this);
import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

browserDynamicPlatform().bootstrapModule(AppModule);
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';

@NgModule({
  imports: [
    BrowserModule
  ],
  declarations: [
    AppComponent
  ],
  providers: [ ],
  bootstrap: [ AppComponent ]
})
export class AppModule {
}