首页 > 代码库 > [Angular] Component architecture and Reactive Forms
[Angular] Component architecture and Reactive Forms
It it recommeded that when deals with form component, we can create a container component to hold state, and then create a stateless component to enpower the form.
For example:
In the example has two components, one is container component ‘meal.component.ts‘, another is statless component ‘meal-form.component.ts‘.
For the container component, it talks to service:
import {Component} from ‘@angular/core‘;import {Meal} from ‘../../../shared/services/meals/meals.service‘;@Component({ selector: ‘meal‘, styleUrls: [‘meal.component.scss‘], template: ` <div class="meal"> <div class="meal__title"> <h1> <img src="/img/food.svg" alt="Food"> <span>Create meal</span> </h1> </div> <div> <meal-form (create)="addMeal($event)" ></meal-form> </div> </div> `})export class MealComponent { constructor() { } addMeal(meal: Meal) { console.log("meal", JSON.stringify(meal, null, 2)) }}
So ‘addMeal‘ function will dispatch action to talk to the service.
For statless component:
import {ChangeDetectionStrategy, Component, EventEmitter, Output} from ‘@angular/core‘;import {FormBuilder, FormArray, FormGroup, FormControl, Validators} from ‘@angular/forms‘;import {Meal} from ‘../../../shared/services/meals/meals.service‘;@Component({ selector: ‘meal-form‘, changeDetection: ChangeDetectionStrategy.OnPush, styleUrls: [‘meal-form.component.scss‘], template: ` <div class="meal-form"> <form [formGroup]="form"> <div class="meal-form__name"> <label> <h3>Meal name</h3> <input type="text" formControlName="name" placeholder="e.g. English Breakfast"> <div class="error" *ngIf="required"> Workout name is required </div> </label> </div> <div class="meal-form__food"> <div class="meal-form__subtitle"> <h3>Food</h3> <button type="button" (click)="addIngredient()" class="meal-form__add"> <img src="/img/add-white.svg" alt="Add food"> Add food </button> </div> <div formArrayName="ingredients"> <label *ngFor="let c of ingredients.controls; index as i;"> <input type="text" [formControlName]="i" placeholder="e.g Eggs"> <span class="meal-form__remove" (click)="removeIngredient(i)" ></span> </label> </div> </div> <div class="meal-form__submit"> <div> <button type="button" class="button" (click)="createMeal()"> Create Meal </button> <a [routerLink]="[‘../‘]" class="button button--cancel"> Cancel </a> </div> </div> </form> </div> `})export class MealFormComponent { @Output() create = new EventEmitter<Meal>(); form = this.fb.group({ name: [‘‘, Validators.required], ingredients: this.fb.array([‘‘]) }); get ingredients () { // Type check for ingredients, mark as FormArray // Therefore when we use ‘ingredients‘, // We can get auto complete return this.form.get(‘ingredients‘) as FormArray; } get required() { return ( this.form.get(‘name‘).hasError(‘required‘) && this.form.get(‘name‘).touched ); } constructor(private fb: FormBuilder) { } createMeal() { if (this.form.valid) { this.create.emit(this.form.value); } } addIngredient() { // Add a new FormControl to FormArray this.ingredients.push(new FormControl(‘‘)); } removeIngredient(i: number) { this.ingredients.removeAt(i); }}
It uses ReactiveForm to create form.
Things to be notice:
1. Add type check for form array:
get ingredients () { // Type check for ingredients, mark as FormArray // Therefore when we use ‘ingredients‘, // We can get auto complete return this.form.get(‘ingredients‘) as FormArray; }
Then whenever you use ‘this.ingredients‘, it will show auto complete.
2. FormArray method:
addIngredient() { // Add a new FormControl to FormArray this.ingredients.push(new FormControl(‘‘)); } removeIngredient(i: number) { this.ingredients.removeAt(i); }
[Angular] Component architecture and Reactive Forms
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。