Download - Angular 2.0 forms
![Page 1: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/1.jpg)
AngularJS 2.0 Forms
Eyal Vardi
Site: http://ng-course.org
Blog: eyalVardi.wordpres.com
![Page 2: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/2.jpg)
Agenda Template Driven
Two-way data binding with ngModel Change tracking with ngControl ngForm
Model Driven Control & ControlGroup Form Builder
Validations Value Accessors
![Page 3: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/3.jpg)
Form Directives (Template Driven)
Installation The forms classes exist in
'angular2/common'import { FORM_DIRECTIVES } from 'angular2/common';
ngFormngFormModel
ngModelngControl
ngFormControl
Controls (Model Driven)
Valid
ator
s
Acce
ssor
s
ControlControlGroupControlArray
![Page 4: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/4.jpg)
My Component
(Model)name: string
Form Control’s Classes
ControlControlGroupControlArray
Component View Template
<input type="text" [(ngModel)] ="name" />
pristine dirty touched untouche
d errors valid
Data Flow
![Page 5: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/5.jpg)
Template Driven
![Page 6: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/6.jpg)
ngModel Directive Binds an existing domain model to a
form control.@Component({ selector: "search-comp", directives: [FORM_DIRECTIVES], template: `<input type='text' [(ngModel)]="name">`})class SearchComp { name: string;}
![Page 7: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/7.jpg)
Inside [(ngModel)] 1/2
<input type="text" class="form-control"
required
[ngModel]="model.name"
(ngModelChange)="model.name =
$event" >
Name: {{model.name}}
Property Binding, a value flows from the model to a target property on screen.
Event Binding, we flow the value from the target property on screen to the model.
![Page 8: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/8.jpg)
Inside [(ngModel)] 2/2@Directive({ selector: '[ngModel]:not([ngControl]):not([ngFormControl])', bindings: [formControlBinding], inputs : ['model: ngModel'], outputs : ['update: ngModelChange'], exportAs: 'ngForm'})export class NgModel extends NgControl implements OnChanges { _control = new Control(); /** @internal */ _added = false; /** @internal */ update = new EventEmitter(); model: any; viewModel: any;
constructor(...) {...} /** Properties & Methods */ }
![Page 9: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/9.jpg)
ngControl Directive (NgControlName) Creates and binds a control with a
specified name to a DOM element.
<form #f="ngForm" (submit)='onLogIn(f.value)'>
Login <input type='text' ngControl='login'
#l="ngForm">
<div *ngIf="!l.valid">Login is invalid</div>
</form>
![Page 10: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/10.jpg)
Component Field
Component Template Directive that in use
name : string
<input [(ngModel)]=“name” /> ngModel
name : string
<input ngControl=“dName” [(ngModel)]=“name” />
ngControlName
ngModel vs. ngControlName ngControlName directive selector
'[ngControl]'
ngModel directive selector '[ngModel]:not([ngControl]):not([ngFormControl])
'
This is still a ngControl
![Page 11: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/11.jpg)
ngControl Properties Properties:
formDirective control value path validator asyncValidator
States Properties: pristine dirty touched untouched errors valid
Abstract class
![Page 12: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/12.jpg)
Track change-state and validity
State Class if true Class if false
Control has been visited ng-touched ng-untouched
Control's value has changed ng-dirty ng-pristine
Control's value is valid ng-valid ng-invalid
![Page 13: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/13.jpg)
NgControlStatus Directive Sets CSS classes based on ngControl
directive status (valid/invalid/dirty/etc).@Directive({ selector: '[ngControl],[ngModel],[ngFormControl]', host: { '[class.ng-untouched]': 'ngClassUntouched', '[class.ng-touched]' : 'ngClassTouched', '[class.ng-pristine]' : 'ngClassPristine', '[class.ng-dirty]' : 'ngClassDirty', '[class.ng-valid]' : 'ngClassValid', '[class.ng-invalid]' : 'ngClassInvalid' }})export class NgControlStatus { private _cd: NgControl; constructor(@Self() cd: NgControl) { this._cd = cd; } ...
get ngClassValid(): boolean { return isPresent(this._cd.control) ? this._cd.control.valid : false; } ...}
![Page 14: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/14.jpg)
Data BindingTrack change-state
and validity
Validators
Control
My Component (model)
![Page 15: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/15.jpg)
ngModel Directives ngControlName
ngFormControl
ngModelselector :
'[ngModel]:not([ngControl]):not([ngFormControl])',Inputs : ['model: ngModel'],
outputs : ['update: ngModelChange'],
selector : '[ngFormControl]'inputs : ['form: ngFormControl', 'model: ngModel'],outputs : ['update: ngModelChange'],
selector : '[ngControl]',inputs : ['name: ngControl', 'model: ngModel'],outputs : ['update: ngModelChange'],
![Page 16: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/16.jpg)
Form Tag & NgForm Directive NgForm will get automatically attached to
any <form> tags you have in your view, when we used FORM_DIRECTIVES. A ControlGroup named ngForm A (ngSubmit) output
<form #f="ngForm" (ngSubmit)="onSubmit(f.value)"></form>
ExportAs
Output
![Page 17: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/17.jpg)
Form Directives
Use on input tagUse on form tag
![Page 18: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/18.jpg)
Errors Messages Form message
Field message
Specific validation
<div *ngIf="!myForm.valid" class="ui error message">Form is invalid
</div>
<div *ngIf="!name.valid" class="ui message" [class.error]="!name.valid && name.touched" >
Name is invalid</div>
<div *ngIf="name.hasError('required')" class="ui error message">Name is required</div>
![Page 19: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/19.jpg)
Model Driven
![Page 20: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/20.jpg)
Form Controls `Control`s have values and validation
state
![Page 21: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/21.jpg)
AbstractControl Class Events:
valueChanges statusChanges
Methods: setErrors,getErrors & hasErrors find setParent markAsDirty,markAsXXX runValidator
Properties: value status valid errors pristine dirty touched untouched
![Page 22: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/22.jpg)
Model Driven Forms A Control represents a single input field Controls encapsulate the field's value,
and states such as if it is valid, dirty (changed), or has errors.
Directives Controls
ngFormModel ControlGroup | ControlArray
ngFormControl Control
![Page 23: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/23.jpg)
ngFormModel & ngFormControl ngFormModel Binds an existing control
group to a DOM element. ngFormControl Binds an existing Control
to a DOM element.
export class App { constructor() { this.myForm = new ControlGroup({ myControl: new Control("") }); }}
<form [ngFormModel]="myForm"> <input ngFormControl="myControl"></form>
![Page 24: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/24.jpg)
FormBuilder Class Creates a form object from a user-
specified configuration. control(value: Object, validator?: Function, asyncValidator?: Function) :
Control group(controls: {[key: string]: any}, extra?: {[key: string]: any}) :
ControlGroup array(controls: any[], validator?: Function, asyncValidator?: Function) :
ControlArrayconstructor(builder: FormBuilder) {
this.loginForm = builder.group({
login: ["", Validators.required],
passwordRetry: builder.group({
password: ["", Validators.required],
pConfirmation: ["", Validators.required]
})
});
}
![Page 25: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/25.jpg)
FormBuilder Class Creates a form object from a user-
specified configuration.@Component({ selector: 'my-app', viewBindings: [FORM_BINDINGS], template: ` <form [ngFormModel]="loginForm"> <p>Login <input ngFormControl="login"></p> <div ngControlGroup="passwordRetry"> <p>Password <input type="password" ngFormControl="password"></p> <p>Confirm password <input type="password" ngFormControl="pConfirma"></p> </div> </form> <h3>Form value:</h3> <pre>{{value}}</pre> `, directives: [FORM_DIRECTIVES]})
export class App { loginForm: ControlGroup; constructor(builder: FormBuilder) { this.loginForm = builder.group({ login: ["", Validators.required], passwordRetry: builder.group({ password: ["", Validators.required], pConfirm: ["", Validators.required] }) }); } get value(): string { return JSON.stringify( this.loginForm.value, null, 2); }}
![Page 26: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/26.jpg)
Watching For Changes Both ControlGroup and Control have an
EventEmitter that we can use to observe changes.this.name.valueChanges.subscribe( (value: string) => { console.log('name changed to: ', value); });
this.myForm.valueChanges.subscribe( (value: string) => { console.log('form changed to: ', value); });
![Page 27: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/27.jpg)
Validations
![Page 28: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/28.jpg)
Built-in Validators Required MaxLength & MinLength
![Page 29: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/29.jpg)
Custom Validator Directive@Directive({ selector: ' [my-validator][ngControl],
[my-validator][ngFormControl], [my-validator][ngModel]', providers: [provide( NG_VALIDATORS, { useExisting: myValidator, multi: true})]})export class myValidator implements Validator { private _validator: Function;
constructor(@Attribute("my-validator") myValidator: string) { this._validator = function(value){ return { "myValidator": true }; } }
validate(c: Control): {[key: string]: any} { return this._validator(c); }}
Returns a StringMap<string, boolean> where the key is "error code" and the value is true if it fails
![Page 30: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/30.jpg)
Custom Validator Assigning the Validator to the Control:
this.myForm = fb.group({ 'name': [
'', Validators.compose([
Validators.required , nameValidator
])]
});
and operation
![Page 31: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/31.jpg)
Value Accessors
![Page 32: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/32.jpg)
Interface ControlValueAccessor A bridge between a control and a native
element. A ControlValueAccessor abstracts the
operations of writing a new value to a DOM element representing an input control.
![Page 33: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/33.jpg)
DefaultValueAccessor Directive The default accessor for writing a value and
listening to changes that is used by the: NgModel NgFormControl NgControlName
InputInput ModelDefaultValueAccessor Renderer On Change
ngModel | ngFormControl | ngControlName
![Page 34: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/34.jpg)
DVA Code@Directive({ selector: 'input:not([type=checkbox])[ngControl],
textarea[ngControl],input:not([type=checkbox])[ngFormControl],textarea[ngFormControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',
host: { '(input)': 'onChange($event.target.value)', '(blur)' : 'onTouched()'},
bindings: [DEFAULT_VALUE_ACCESSOR]}) export class DefaultValueAccessor implements ControlValueAccessor { onChange = (_) => {}; onTouched = () => {};
constructor(private _renderer:Renderer, private _elementRef:ElementRef) {}
writeValue(value: any): void { var normalizedValue = isBlank(value) ? '' : value; this._renderer.setElementProperty(
this._elementRef, 'value', normalizedValue); } registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; }}
![Page 35: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/35.jpg)
setUpControl function This function are call when the
ngOnChanges in ngModel directive is call in the first time.
export function setUpControl( control: Control , dir: NgControl ): void {
...
dir.valueAccessor.writeValue(control.value);
// view -> model dir.valueAccessor.registerOnChange(newValue => { dir.viewToModelUpdate(newValue); control.updateValue(newValue, {emitModelToViewChange: false}); control.markAsDirty(); });
// model -> view control.registerOnChange(newValue => dir.valueAccessor.writeValue(newValue));
// touched dir.valueAccessor.registerOnTouched(() => control.markAsTouched());}
![Page 36: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/36.jpg)
Form Classes
![Page 37: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/37.jpg)
Resources Angular.io site (Developer guides - forms) Ng-Book 2 (
The Ultimate Guide to Forms in Angular 2 ) GitHub (Angular code source)
![Page 38: Angular 2.0 forms](https://reader030.vdocuments.net/reader030/viewer/2022012917/58819dab1a28ab1a398b489f/html5/thumbnails/38.jpg)
Thankseyalvardi.wordpress.com
Eyal Vardi
Site: http://ng-course.org
Blog: eyalVardi.wordpres.com