<!DOCTYPE html>
<html>
<head>
<base href="." />
<title>angular2 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">
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></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>
<body>
<my-app>
loading...
</my-app>
</body>
</html>
/* Styles go here */
### Angular Starter Plunker - Typescript
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/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
'@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
'@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
'@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
'@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
'@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
'rxjs': 'npm:rxjs',
'typescript': 'npm:typescript@2.0.2/lib/typescript.js'
},
//packages defines our app package
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
}
}
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';
platformBrowserDynamic().bootstrapModule(AppModule)
//our root app component
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { DataDrivenComponent } from "./data-driven.component";
@Component({
selector: 'my-app',
template: `
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>Forms (Data Driven)</h1>
<data-driven></data-driven>
<hr>
</div>
</div>
</div>
`,
})
export class App {
name:string;
constructor() {
this.name = 'Angular2'
}
}
@NgModule({
imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
declarations: [ App, DataDrivenComponent ],
bootstrap: [ App ]
})
export class AppModule {}
import { Component } from '@angular/core';
import {FormGroup, FormControl, Validators, FormArray, FormBuilder} from "@angular/forms";
import {Observable} from "rxjs";
@Component({
selector: 'data-driven',
templateUrl: './src/data-driven.component.html',
styles: [`
.glyphicon-refresh-animate {
-animation: spin .7s infinite linear;
-webkit-animation: spin2 .7s infinite linear;
}
@-webkit-keyframes spin2 {
from { -webkit-transform: rotate(0deg);}
to { -webkit-transform: rotate(360deg);}
}
@keyframes spin {
from { transform: scale(1) rotate(0deg);}
to { transform: scale(1) rotate(360deg);}
}
`]
})
export class DataDrivenComponent {
myForm: FormGroup;
public loading: boolean = false;
constructor(private formbuilder: FormBuilder) {
this.myForm = formbuilder.group({
'hobbies': formbuilder.array([
['Cooking', this.asyncExampleValidator.bind(this)]
])
});
}
onAddHobby() {
(<FormArray>this.myForm.get('hobbies')).push(new FormControl('', Validators.required, this.asyncExampleValidator.bind(this)));
}
/**
* @param control
* @return {Promise<any>}
*/
asyncExampleValidator(control: FormControl): Promise<any> | Observable<any> {
var that = this;
//console.log(this);
const promise = new Promise<any>(
(resolve, reject) => {
that.loading = true;
setTimeout(() => {
that.loading = false;
if (control.value === '') {
console.log('Invalid');
resolve({'invalid': true});
}
else {
console.log('Valid');
resolve(null);
}
}, 1500);
}
);
return promise;
}
}
<h1>Data Driven</h1>
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<div formArrayName="hobbies">
<h3>Hobbies</h3>
<!-- Por cada control del array de controles creado en el código, añadimos su correspondiente html -->
<div class="form-group" *ngFor="let hobby of myForm.get('hobbies').controls; let i = index">
<!-- Notar que se usa string interpolation {{i}} porque la directiva formControName no usa data binding -->
<input type="text"
class="form-control" formControlName="{{i}}">
</div>
</div>
<button type="button" class="btn btn-default" (click)="onAddHobby()">Add Hobby</button>
<!-- Fijarse en como lo hacemos en Template Driven Approach: añadimos variable local
#formulario="ngForm" en la etiqueta <form>, y accedemos al valor de la propiedad disabled
del botón mediante [disabled]="!formulario.valid" -->
<button type="submit" class="btn btn-primary" [disabled]="!myForm.valid">Submit<i *ngIf="loading" class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></i></button>
</form>