<!DOCTYPE html>
<html>

<head>
  <base href="." />
  <script type="text/javascript" charset="utf-8">
    window.AngularVersionForThisPlunker = '4.3.6' // Latest version 27/08/2017
  </script>
  <title>angular playground</title>
  <link rel="stylesheet" href="style.css" />
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
  
  <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
  <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
  <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
  <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
  <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
  <script src="config.js"></script>
  <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
</head>
<br>

<body class='container'>
  <h3>By <a href='http://www.advancesharp.com/blog/1214/angular-2-dynamically-add-remove-components'>Advancesharp.com</a> </h3>
  <my-app>
    loading...
  </my-app>
</body>

</html>

.row{
    margin-bottom: 10px;
}
var angularVersion;
if(window.AngularVersionForThisPlunker === 'latest'){
  angularVersion = ''; //picks up latest
}
else {
  angularVersion = '@' + window.AngularVersionForThisPlunker;
}

System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    '@angular/core': 'npm:@angular/core'+ angularVersion + '/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common' + angularVersion + '/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler' + angularVersion  + '/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic' + angularVersion + '/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http' + angularVersion + '/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router' + angularVersion +'/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms' + angularVersion + '/bundles/forms.umd.js',
    '@angular/animations': 'npm:@angular/animations' + angularVersion + '/bundles/animations.umd.js',
    '@angular/platform-browser/animations': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser-animations.umd.js',
    '@angular/animations/browser': 'npm:@angular/animations' + angularVersion + '/bundles/animations-browser.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core' + angularVersion + '/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common' + angularVersion + '/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler' + angularVersion + '/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic' + angularVersion + '/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http' + angularVersion + '/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router' + angularVersion + '/bundles/router-testing.umd.js',
    'tslib': 'npm:tslib@1.6.1',
    'rxjs': 'npm:rxjs',
    'typescript': 'npm:typescript@2.2.1/lib/typescript.js'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
import {NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormsModule } from '@angular/forms';
import {Router} from '@angular/router'

import { AppComponent } from './app/app.component';
import { AddEditComponent } from './app/addedit.component';
import { CustomersComponent } from './app/customers.component';

    
@NgModule({
  imports: [
    BrowserModule, FormsModule
  ],
  declarations: [ AppComponent, AddEditComponent, CustomersComponent ],
  exports: [],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';


platformBrowserDynamic().bootstrapModule(AppModule)
import {Component} from '@angular/core'
import { Component, OnInit } from '@angular/core';


@Component({
  selector: 'my-app',
  templateUrl: './src/app/app.component.html'
})
export class AppComponent implements OnInit{ 
   customers : Array<any>;
   constructor() { }
   ngOnInit(){
     
   }
   
   getCustomers(){
     this.customers = localStorage.getItem
   }
   
}

<fieldset>
  <legend>Add/Edit Customer</legend>


    <form >
      <div class="form-group row">
        <label for="name" class="col-md-1 col-form-label">Name</label>
        <div class="col-md-5">          
            <input type="text" id="name" name='name'
              class="form-control"
              placeholder="Customer Name"
              [(ngModel)]="customer.name">
        </div>
      </div>
      <div class="form-group row">
        <label for="address" class="col-sm-1 col-form-label">Address</label>
        <div class="col-md-5">          
            <input type="text" id="address" name='address'
              class="form-control"
              placeholder="Customer Address"
              [(ngModel)]="customer.address">
        </div>
      </div>
      <div class="form-group row">
        <div class="col-md-5 col-md-offset-1">   
          <input type="submit" class="btn btn-primary" value='Save' (click)='save()'>
          <input type="button" class="btn btn-warning" value='Clear' (click)='clear()'>
        </div>
      </div>      
    </form>
</fieldset>


import { Component, OnInit, Input, Output,EventEmitter } from '@angular/core';
import { CustomerModel } from './app.model';
import { DataService } from './data.service';

@Component({
  selector: 'addedit-customer',
  templateUrl: './src/app/addedit.component.html'
})
export class AddEditComponent {
  @Input() customer: CustomerModel;
  @Output() status = new EventEmitter();
  
  constructor() { }

  ngOnInit() {
    this.clear();
  }

  save(){
    DataService.save(this.customer);
    this.status.emit(true);  
    this.clear();  
  }
  clear(){
    this.customer = new CustomerModel();
    this.status.emit(false);
  }
}


<customers-list></customers-list>
export class CustomerModel{
    id:number = 0;
    name: string;
    addresss: string;
}
import { Injectable } from '@angular/core';

@Injectable()
export class DataService {

  constructor() { }

  static save(customer){
    var records = [];
    if(localStorage.getItem('records'))
       records = JSON.parse(localStorage.getItem('records'));

    if(customer.id > 0){
      for(var i=0; i < records.length; i++){
        if(records[i].id == customer.id)
        records[i] = customer;
      }
    }else{
      customer.id = records.length + 1;
      records.push(customer);
    }
    localStorage.setItem('records', JSON.stringify(records));
  }

  static getById(id){
    var records = [];
    if(localStorage.getItem('records')){
       records = JSON.parse(localStorage.getItem('records'));
       return records.map(x=>{ if(x.id == id) return x; })
    }
  }

  static getCustomers(){
    var records = [];
    if(localStorage.getItem('records')){
       records = JSON.parse(localStorage.getItem('records'));
    }
    return records;
  }

  static deleteCustomer(id){
    var records = [];
    if(localStorage.getItem('records')){
       records = JSON.parse(localStorage.getItem('records'));
       var index = records.map(x=> {return x.id}).indexOf(id);
       records.splice(index, 1);
       localStorage.setItem('records', JSON.stringify(records));
    }
  }

}
import { Component, OnInit } from '@angular/core';
import { CustomerModel } from './app.model';
import { DataService } from './data.service';

@Component({
  selector: 'customers-list',
  templateUrl: './src/app/customers.component.html'
})
export class CustomersComponent implements OnInit {
  customer: CustomerModel;
  customers: Array<CustomerModel> = [];
  constructor() { 
    this.customer = new CustomerModel();
  }

  ngOnInit() {
    this.getCustomers();
  }

  getCustomers(){
      this.customers = DataService.getCustomers();
  }

  edit(record){
    this.customer = Object.assign({}, record) ;
  }

  delete(id){
    DataService.deleteCustomer(id);
  }

  saveStatus(event){
    if(event== true)
      this.customers = DataService.getCustomers();
  }
}

<fieldset>
  <legend>Customer List</legend>
  
  <table class="table table-bordered">
    <tr>
      <th>ID</th>
      <th>Customer Name</th>
      <th>Address</th>
      <th>Actions</th>
    </tr>
    <tr *ngFor="let customer of customers">
      <td>{{customer.id}}</td>
      <td>{{customer.name}}</td>
      <td>{{customer.address}}</td>
      <td>
          <i class="fa fa-pencil-square-o fa-lg" 
             style='cursor:pointer' title='Edit'
             aria-hidden="true" (click)='edit(customer)'></i>
          
          <i class="fa fa-trash fa-lg" 
             style='cursor:pointer'  title='Remove'
             aria-hidden="true" (click)='delete(customer.id)'></i>
      </td>
    </tr>
  </table>

  <div class="well">
    <addedit-customer [customer]="customer"
        (status)='saveStatus($event)'></addedit-customer>
  </div>
</fieldset>