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:

  1. import {Component} from '@angular/core';
  2. import {Meal} from '../../../shared/services/meals/meals.service';
  3. @Component({
  4. selector: 'meal',
  5. styleUrls: ['meal.component.scss'],
  6. template: `
  7. <div class="meal">
  8. <div class="meal__title">
  9. <h1>
  10. <img src="/img/food.svg" alt="Food">
  11. <span>Create meal</span>
  12. </h1>
  13. </div>
  14. <div>
  15. <meal-form
  16. (create)="addMeal($event)"
  17. ></meal-form>
  18. </div>
  19. </div>
  20. `
  21. })
  22. export class MealComponent {
  23. constructor() {
  24.  
  25. }
  26.  
  27. addMeal(meal: Meal) {
  28. console.log("meal", JSON.stringify(meal, null, 2))
  29. }
  30. }

So 'addMeal' function will dispatch action to talk to the service.

For statless component:

  1. import {ChangeDetectionStrategy, Component, EventEmitter, Output} from '@angular/core';
  2. import {FormBuilder, FormArray, FormGroup, FormControl, Validators} from '@angular/forms';
  3. import {Meal} from '../../../shared/services/meals/meals.service';
  4. @Component({
  5. selector: 'meal-form',
  6. changeDetection: ChangeDetectionStrategy.OnPush,
  7. styleUrls: ['meal-form.component.scss'],
  8. template: `
  9. <div class="meal-form">
  10. <form [formGroup]="form">
  11. <div class="meal-form__name">
  12. <label>
  13. <h3>Meal name</h3>
  14. <input type="text"
  15. formControlName="name"
  16. placeholder="e.g. English Breakfast">
  17. <div class="error" *ngIf="required">
  18. Workout name is required
  19. </div>
  20. </label>
  21. </div>
  22.  
  23. <div class="meal-form__food">
  24. <div class="meal-form__subtitle">
  25. <h3>Food</h3>
  26. <button
  27. type="button"
  28. (click)="addIngredient()"
  29. class="meal-form__add">
  30. <img src="/img/add-white.svg" alt="Add food">
  31. Add food
  32. </button>
  33. </div>
  34. <div formArrayName="ingredients">
  35. <label *ngFor="let c of ingredients.controls; index as i;">
  36. <input type="text" [formControlName]="i" placeholder="e.g Eggs">
  37. <span
  38. class="meal-form__remove"
  39. (click)="removeIngredient(i)"
  40. ></span>
  41. </label>
  42. </div>
  43. </div>
  44.  
  45. <div class="meal-form__submit">
  46. <div>
  47. <button type="button" class="button" (click)="createMeal()">
  48. Create Meal
  49. </button>
  50. <a
  51. [routerLink]="['../']"
  52. class="button button--cancel">
  53. Cancel
  54. </a>
  55. </div>
  56. </div>
  57. </form>
  58. </div>
  59. `
  60. })
  61. export class MealFormComponent {
  62.  
  63. @Output()
  64. create = new EventEmitter<Meal>();
  65.  
  66. form = this.fb.group({
  67. name: ['', Validators.required],
  68. ingredients: this.fb.array([''])
  69. });
  70.  
  71. get ingredients () {
  72. // Type check for ingredients, mark as FormArray
  73. // Therefore when we use 'ingredients',
  74. // We can get auto complete
  75. return this.form.get('ingredients') as FormArray;
  76. }
  77.  
  78. get required() {
  79. return (
  80. this.form.get('name').hasError('required') &&
  81. this.form.get('name').touched
  82. );
  83. }
  84.  
  85. constructor(private fb: FormBuilder) {
  86.  
  87. }
  88.  
  89. createMeal() {
  90. if (this.form.valid) {
  91. this.create.emit(this.form.value);
  92. }
  93. }
  94.  
  95. addIngredient() {
  96. // Add a new FormControl to FormArray
  97. this.ingredients.push(new FormControl(''));
  98. }
  99.  
  100. removeIngredient(i: number) {
  101. this.ingredients.removeAt(i);
  102. }
  103. }

It uses ReactiveForm to create form.

Things to be notice:

1. Add type check for form array:

  1. get ingredients () {
  2. // Type check for ingredients, mark as FormArray
  3. // Therefore when we use 'ingredients',
  4. // We can get auto complete
  5. return this.form.get('ingredients') as FormArray;
  6. }

Then whenever you use 'this.ingredients', it will show auto complete.

2. FormArray method:

  1. addIngredient() {
  2. // Add a new FormControl to FormArray
  3. this.ingredients.push(new FormControl(''));
  4. }
  5.  
  6. removeIngredient(i: number) {
  7. this.ingredients.removeAt(i);
  8. }

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

  1. Angular Reactive Forms -- Model-Driven Forms响应式表单

    Angular 4.x 中有两种表单: Template-Driven Forms - 模板驱动式表单 (类似于 AngularJS 1.x 中的表单 )  官方文档:https://v2.angul ...

  2. [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 HT ...

  3. Angular开发实践(三):剖析Angular Component

    Web Component 在介绍Angular Component之前,我们先简单了解下W3C Web Components 定义 W3C为统一组件化标准方式,提出Web Component的标准. ...

  4. Angular之响应式表单 ( Reactive Forms )

    项目结构 一 首页 ( index.html ) <!doctype html> <html lang="en"> <head> <met ...

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

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

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

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

  7. Angular 2 Architecture Overview

    Module 简单来说模块(module)就是完成共同目的的代码块,export一些内容例如一个类.函数.或值变量. component就是一个基本的Angular块,一个component类其实也是 ...

  8. [Angular] Refactor Angular Component State Logic into Directives

    Allow the base toggle to be a tag (<toggle>) or attribute (<div toggle>). The <toggle ...

  9. [Angular] Component's dependency injection

    An Angular service registered on the NgModule is globally visible on the entire application. Moreove ...

随机推荐

  1. Tiling POJ 2506 【大数】

    id=2506">http://poj.org/problem?id=2506 Description In how many ways can you tile a 2xn rect ...

  2. Floodlight中 处理packetin消息的顺序(2)

         前面通过阅读代码知道了怎样推断各个模块处理某个消息的先后顺序.那么内部是怎样实现的呢?      每当一个模块表示对一个消息感兴趣的时候,就会调用IFloodlightProviderSer ...

  3. 在vim中配置python补全,fedora 19

    近期发现python是个不错的语言,值得一学,先配置下环境,让vim具有keyword补全功能,步骤例如以下,我这个是fedora,其它发行版类似 $ su ******** # yum instal ...

  4. vim 基础学习之可视模式

    1. 选择模式这个模式必须通过可视模式进入.在可视模式下,我们通过 <C-g>来把我们的可视选中块作为选择模式下的操作块. 这时候我们输入可见字符,就会把这个块给覆盖掉.例如aaa bbb ...

  5. HDU 2102 A计划 (三维的迷宫BFS)

    题目链接:pid=2102">传送门 题意: 三维的一个迷宫,起点在第一层的S(0,0,0)处,问是否能在规定的时间内走到第二层的P 处.'*'代表不能走,'.'代表能够走,'#'代表 ...

  6. CSS控制显示超出部分,用省略号显示

    经常使用.可是常忘,我又不是写css的.所以记下来: 先设置一下限制的宽度, display:block; white-space:nowrap; overflow:hidden; text-over ...

  7. WebService三大基本元素 SOAP WSDL UDDI

    转自:https://blog.csdn.net/hhooong/article/details/51763128 1.SOAP 即 Simple Object AccessProtocol 也就是简 ...

  8. MD5和sha1加密算法--散列加密技术 MD5:128bit的大整数

    在很多电子商务和社区应用中,我们都要存放很多的客户的资料,其中包括了很多的隐私信息和客户不愿被别人看到的信息,当然好有客户执行各种操作的密码,此时就需要对客户的信息进行加密再存储,目前有两种比较好的加 ...

  9. BZOJ1503: [NOI2004]郁闷的出纳员(Splay)

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的 工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经 ...

  10. VMware Tools安装问题的解决

    一.VMware Tools工具的作用 VMware虚拟机的插件工具,安装上它可以实现主机与虚拟机的文件共享及拖放.简单的说就是从Ubuntu上边经常输入命令行会出现错误的情况,需要复制到Window ...