Formulare in Angular – Varianten, Konzepte und Umsetzung

Formulare in Angular – Varianten, Konzepte und Umsetzung

Formulare bilden die Grundlage vieler Line-of-Business Applikationen, besonders im Web. Seit Angular 2 gibt es neben dem Konzept der Template-Driven Forms auch das Konzept der Reactive-Forms. In dieser Session lernen Sie Schritt für Schritt wie mit den beiden Varianten Formulare aufgebaut, validiert und abgeschickt werden. Die beiden Varianten werden im Detail erläutert, verglichen und wir finden heraus, für welche Anwendungsfälle welche Technologie Vorteile bietet.

F8980be26d3f8c298c19e3e30ac0dbe1?s=128

Thomas Gassmann

October 17, 2018
Tweet

Transcript

  1. 3.

    Agenda 17.10.2018 WDC - Formulare in Angular 3 ▪ Introduction

    ▪ Template-Driven Forms ▪ Reactive Forms ▪ Custom Controls
  2. 5.

    Form technologies 17.10.2018 WDC - Formulare in Angular 5 Template-driven

    Forms ▪ Use a Component’s Template ▪ Unit Test against DOM Reactive Forms ▪ Use a Component’s Template ▪ Create a Form Model in TypeScript ▪ Unit Test against Form Model ▪ Validation in Form Model
  3. 6.

    Building Blocks: State 17.10.2018 WDC - Formulare in Angular 6

    Value Changed: pristine dirty Validity: valid invalid Visited: touched untouched
  4. 7.

    Building Blocks 17.10.2018 WDC - Formulare in Angular 7 FormControl

    Tracks state of an individual input FormGroup Tracks state of a group of FormControls
  5. 8.

    Form Model 17.10.2018 WDC - Formulare in Angular 8 ▪

    Instances of FormControl or FormGroup ▪ Retains form state ▪ Retains form value ▪ Retains child controls (FormControls or FormGroups)
  6. 9.

    Template-Driven Forms 17.10.2018 WDC - Formulare in Angular 9 ▪

    Kind of forms used with Angular 1.x ▪ Bind directives and behavious to your templates ▪ Used with ngModel, required, minlength etc. ▪ The template is doing the work ▪ Angular automatically generates our FormModel
  7. 10.

    Reactive Forms 17.10.2018 WDC - Formulare in Angular 10 ▪

    Also known as model-driven ▪ Avoiding directives such as ngModel, required etc. ▪ Use the underlying APIs to do the work by creating a instance inside a component class and construct JavaScript models. ▪ Very testable ▪ Keeps all logic in the same place
  8. 11.

    Directives: Template-Driven 17.10.2018 WDC - Formulare in Angular 11 <form

    #f="ngForm" (ngSubmit)="save()"> <input type="text" name="firstname" [(ngModel)]="employee.firstname"> </form> ▪ ngForm ▪ ngModel ▪ ngModelGroup
  9. 12.

    Directives: Reactive Forms 17.10.2018 WDC - Formulare in Angular 12

    <form [formGroup]="form" (ngSubmit)="save()"> <input type="text" formControlName="firstname"> </form> ▪ formGroup ▪ formControl ▪ formControlName ▪ formGroupName
  10. 13.

    Starting Position 17.10.2018 WDC - Formulare in Angular 13 <form

    novalidate> <!– only for Angular<4 --> <div class="form-group row"> <label>Firstname</label> <input type="text" class="form-control"> </div> <div class="form-group row"> <label>Lastname</label> <input type="text" class="form-control"> </div> <div class="form-group row"> <label>Email</label> <input type="text" class="form-control"> </div> <div class="form-group row"> <label>Confirm Email</label> <input type="text" class="form-control"> </div> <button type="submit"> Save </button> </form>
  11. 15.

    Template-Driven Forms 17.10.2018 WDC - Formulare in Angular 15 import

    { FormsModule } from '@angular/forms’; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { } ▪ Add the FormsModule to your AppModule to use ngModel
  12. 16.

    Template-Driven Forms 17.10.2018 WDC - Formulare in Angular 16 @Component({...

    templateUrl: 'employee-form.component.html' }) export class EmployeeFormComponent { employee:Employee = {firstname: 'Thomas', lastname: 'Gassmann', email: 'thomas.gassmann@trivadis.com'}; } ▪ Declare our model class
  13. 17.

    Template-Driven Forms 17.10.2018 WDC - Formulare in Angular 17 <form

    #f="ngForm"> <div class="form-group row"> <label>Firstname</label> <input type="text" name="firstname" [(ngModel)]="employee.firstname" class="form-control"> </div> </form> ▪ Binding ngForm and ngModel
  14. 18.

    Template-Driven Forms 17.10.2018 WDC - Formulare in Angular 18 <form

    (ngSubmit)="onSubmit(f)" #f="ngForm"> … </form> ▪ Add submit functionality by adding the ngSubmit export class AppComponent { employee:Employee= {…}; onSubmit({ valid }: { valid: boolean }) { console.log(valid) } }
  15. 19.

    Template-Driven Forms: Error Validation 17.10.2018 WDC - Formulare in Angular

    19 ▪ Disabling our submit button until the form is valid <form (ngSubmit)="onSubmit(f)" #f="ngForm"> … <button type="submit" [disabled]="f.invalid">Save</button> </form>
  16. 20.

    Template-Driven Forms: Error Validation 17.10.2018 WDC - Formulare in Angular

    20 ▪ Add required and show error message if needed … <input type="text" name="firstname" [(ngModel)]= "employee.firstname" required> <div *ngIf="f.controls.firstname?.errors?.required"> Firstname is required </div> …
  17. 21.

    Template-Driven Forms: Error Validation 17.10.2018 WDC - Formulare in Angular

    21 ▪ Extend our forms with nested objects and data <input type="text" name="firstname" #firstname="ngModel" [(ngModel)]= "employee.firstname" required> <div *ngIf="firstname.errors?.required && firstname.touched" class="error"> Firstname is required </div>
  18. 24.

    Reactive Forms 17.10.2018 WDC - Formulare in Angular 24 import

    { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ BrowserModule, ReactiveFormsModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { } ▪ Add the ReactiveFormsModule to your AppModule
  19. 25.

    Reactive Forms 17.10.2018 WDC - Formulare in Angular 25 ngOnInit()

    { this.form = new FormGroup({ firstname: new FormControl('tga'), email: new FormControl('foo@bar.com') }); } ▪ Create our FormModel
  20. 26.

    Reactive Forms 17.10.2018 WDC - Formulare in Angular 26 <form

    [formGroup]="employee"> <label> <span>Firstname</span> <input type="text" formControlName="firstname"> </label> … </form> ▪ Add formGroup and formControlName on the form
  21. 27.

    Reactive Forms 17.10.2018 WDC - Formulare in Angular 27 this.employee.setValue({

    firstname: 'Thomas’, lastname: 'Gassmann', email: 'tga@tvd.ch' }); // OR this.form.patchValue({ firstname: 'Thomas' }); ▪ Set a value from our model use setValue or patchValue
  22. 28.

    Reactive Forms 17.10.2018 WDC - Formulare in Angular 28 <form

    (ngSubmit)="onSubmit()" [formGroup]="form"> … </form> ▪ Add submit functionality by adding the ngSubmit export class AppComponent { form:FormGroup= {…}; onSubmit() { console.log(form.valid) } }
  23. 29.

    Reactive Forms: Error Validation 17.10.2018 WDC - Formulare in Angular

    29 ▪ Disabling our submit button until the form is valid <form (ngSubmit)="onSubmit()" [formGroup]="form"> … <button type="submit" [disabled]="form.invalid">Save</button> </form>
  24. 30.

    Reactive Forms: Error Validation 17.10.2018 WDC - Formulare in Angular

    30 @Component({...}) export class EmployeeFormComponent { form:FormGroup; ngOnInit() { this.form = new FormGroup({ firstname: new FormControl('', Validators.required), email: new FormControl('', [Validators.required, Validators.minLength(2)]), }); } }
  25. 31.

    Reactive Forms: Error Validation 17.10.2018 WDC - Formulare in Angular

    31 ▪ Use .get() method that will look up for the control <div *ngIf="form.get('firstname').hasError('required') && form.get('firstname').touched"> Firstname is required </div>
  26. 32.

    Reactive Forms: Error Validation 17.10.2018 WDC - Formulare in Angular

    32 @Component({...}) export class EmployeeFormComponent { form:FormGroup; ngOnInit() { this.form = new FormGroup({ firstname: new FormControl('', Validators.required), email: new FormControl('', [Validators.required, Validators.minLength(2)]), }); } }
  27. 33.

    Reactive Forms - FormBuilder 17.10.2018 WDC - Formulare in Angular

    33 ▪ Usage of FormGroup and FormControl is complex ▪ Let’s simplify it with FormBuilder ▪ FormBuilder is a helper class to build forms ▪ It is a flexible and common way to configure forms
  28. 34.

    Reactive Forms - FormBuilder 17.10.2018 WDC - Formulare in Angular

    34 constructor(private fb: FormBuilder) {} ngOnInit() { this.form = this.fb.group({ firstname: ['', Validators.required], email: ['', [Validators.required,Validators.minLength(4)]], }); }
  29. 37.

    ControlValueAccessor 17.10.2018 WDC - Formulare in Angular 37 ▪ «Bridge»

    between model and view/DOM ▪ Interface which takes care of writing a value and inform about changes ▪ There is a ControlValueAccessor for every input type
  30. 38.

    Implementing ControlValueAccessor 17.10.2018 WDC - Formulare in Angular 38 export

    interface ControlValueAccessor { // writes a new value writeValue(obj: any) : void // registers a handler that should be called when something in the view has changed registerOnChange(fn: any) : void // registers a handler specifically for when a control receives a touch event registerOnTouched(fn: any) : void }
  31. 39.

    Registering the ControlValueAccessor 17.10.2018 WDC - Formulare in Angular 39

    @Component({ … providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EmployeeRatingComponent), multi: true } ] }) export class EmployeeRatingComponent implements ControlValueAccessor { }
  32. 40.

    Employee Rating 17.10.2018 WDC - Formulare in Angular 40 writeValue(value:

    number): void { if (value) { this.counterValue = value; } } registerOnChange(fn: (rating: number) => void) { this.propagateChange = fn; } registerOnTouched(fn: () => void) { this.propagateTouched = fn; }
  33. 42.

    updateOn option 17.10.2018 WDC - Formulare in Angular 42 ▪

    Updating on every keystroke can sometimes be too expensive ▪ Angular 5 provides a new option that improves performance by delaying form control updates until the blur or the submit event. email: new FormControl(null, { validators: Validators.required, updateOn: 'blur' }),
  34. 43.

    When use Reactive Forms 17.10.2018 WDC - Formulare in Angular

    43 ▪ Dynamically add input elements ▪ Watch what the user types ▪ Different validation for different situations ▪ Immutable data structures
  35. 44.

    Summary 17.10.2018 WDC - Formulare in Angular 44 Template-Driven ▪

    Generated form model ▪ HTML validation ▪ Two-way data binding Reactive Forms ▪ Manually created form model ▪ Validation in the class ▪ No two-way data binding
  36. 45.

    Ressources 17.10.2018 WDC - Formulare in Angular 45 ▪ github.com/gassmannT/AngularForms

    ▪ thomasgassmann.net ▪ swissangular.com ▪ m.trivadis.com/angular ▪ angular-academy.ch
  37. 47.