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. Formulare in Angular Web Developer Conference 17.10.2018 Thomas Gassmann @gassmannT

  2. Thomas Gassmann Senior Consultant, Trainer, Speaker thomasgassmann.net @gassmannT 17.10.2018 WDC

    - Formulare in Angular 2
  3. Agenda 17.10.2018 WDC - Formulare in Angular 3 ▪ Introduction

    ▪ Template-Driven Forms ▪ Reactive Forms ▪ Custom Controls
  4. Angular Forms 17.10.2018 WDC - Formulare in Angular 4

  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
  6. Building Blocks: State 17.10.2018 WDC - Formulare in Angular 6

    Value Changed: pristine dirty Validity: valid invalid Visited: touched untouched
  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
  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)
  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
  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
  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
  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
  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>
  14. Template Driven Forms 17.10.2018 WDC - Formulare in Angular 14

  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
  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
  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
  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) } }
  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>
  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> …
  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>
  22. Demo 13.09.2018 Swiss Angular Meetup - Angular Elements 22

  23. Reactive Form 17.10.2018 WDC - Formulare in Angular 23

  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
  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
  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
  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
  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) } }
  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>
  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)]), }); } }
  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>
  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)]), }); } }
  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
  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)]], }); }
  35. Demo 13.09.2018 Swiss Angular Meetup - Angular Elements 35

  36. Custom Control 17.10.2018 WDC - Formulare in Angular 36

  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
  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 }
  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 { }
  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; }
  41. Demo 13.09.2018 Swiss Angular Meetup - Angular Elements 41

  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' }),
  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
  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
  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
  46. Thank you Thomas Gassmann @gassmannT thomasgassmann.net thomas.gassmann@trivadis.com 17.10.2018 WDC -

    Formulare in Angular 46
  47. None