[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);
  }
时间: 2024-12-29 17:19:57

[Angular] Component architecture and Reactive Forms的相关文章

[Angular] Create a custom validator for reactive forms in Angular

Also check: directive for form validation User input validation is a core part of creating proper HTML forms. Form validators not only help you to get better quality data but they also guide the user through your form. Angular comes with a series of

Reactive Forms

Angular 4.x 中有两种表单: Template-Driven Forms - 模板驱动式表单 (类似于 AngularJS 1.x 中的表单 ) Reactive Forms (Model-Driven Forms) - 响应式表单 Template-Driven Forms vs Reactive Forms Template-Driven Forms (模板驱动表单) 的特点 使用方便 适用于简单的场景 通过 [(ngModel)] 实现数据双向绑定 最小化组件类的代码 不易于单元

ng2响应式表单-翻译与概括官网REACTIVE FORMS页面

本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将解释响应式表单并用来创建一个英雄详情编辑器. 包含内容: 响应式表单介绍 开始搭建 创建数据模型 创建响应式的表单组件 创建组建的模板文件 引入ReactiveFormsModule 显示HeroDetailComponent 添加一个FormGroup 看看表单模型 介绍FormBuilder 验

Angular 2 Architecture Overview

Module 简单来说模块(module)就是完成共同目的的代码块,export一些内容例如一个类.函数.或值变量. component就是一个基本的Angular块,一个component类其实也是我们从模块中export出来的东西. Angular本身也是一个有着许多称为“barrels”的库模块的集合.angular2/core 是最主要的Angular库模块. 如果引入的是Angular本身的库模块,import语句直接引用的是模块的名称:如果引入的是自己本地的模块,则需要使用相对路径,

[Angular] Expose Angular Component Logic Using State Reducers

A component author has no way of knowing which state changes a consumer will want to override, but state reducers handle this problem by allowing the parent component to override any state change. In Short, we want to have a way to override the compo

angular reactive form

这篇文章讲了angular reactive form, 这里是angular file upload 组件 https://malcoded.com/posts/angular-file-upload-component-with-express/ 原文:https://malcoded.com/posts/angular-fundamentals-reactive-forms/ ------------------------------------ Forms are arguably o

angular custom Element 自定义web component

angular 自定义web组件: 首先创建一个名为myCustom的组件. 引入app.module: ... import {customComponent} from ' ./myCustom.component'; @NgModule({ declarations:[AppComponent,customComponent], entryComponents:[customComponent] .... }) export class AppModule{} 全局注册: app.comp

来自 Thoughtram 的 Angular 2 系列资料

Angular 2 已经正式 Release 了,Thoughtram 已经发布了一系列的文档,对 Angular 2 的各个方面进行深入的阐释和说明. 我计划逐渐将这个系列翻译出来,以便对大家学习 Angular 2 提供一些方便. Getting Started Building a Zippy component in Angular 2 Developing a Tabs component in Angular 2 Angular 2 Template Syntax demystifi

Template-Driven Forms

Angular 4.x 中有两种表单: Template-Driven Forms - 模板驱动式表单 (类似于 AngularJS 1.x 中的表单 ) Reactive Forms - 响应式表单 本文主要介绍 Template-Driven Forms (模板驱动式表单) ,将涉及 ngForm.ngModel.ngModelGroup.表单提交事件.表单验证和异常信息输出等内容. User interface // signup.interface.ts export interface