[Angular] Reactive Form -- FormControl & formControlName, FormGroup, formGroup & formGroupName

First time dealing with Reactive form might be a little bit hard to understand. 

I have used Angular-formly for AngularJS bofore, what it does is using Javascript to define form's template, data and validations.  In HTML, it is just a simple directive with some bindings. 

<form>
  <angular-formly model="$ctrl.model" options="$ctrl.options" form="$ctrl.form" fields="$ctrl.fields"></angular-formly>
</form>

So what is the main difference between Angular Formly and Reactive Form for Angular (v >= 2.0)?

Well, the main difference is that "Reactive form return the template part to the html, only take care of data and validations". So what it means is that when you use Reactive form, you still need to structure what your form should looks like by using HTML. But data bindings and validations will be taken over by Angular. 

So what is the benenfits by doing "return template part to the html"?  Well this allows user passing custom components and bind those components to the reactive form really easily.

Of course, in Angular Formly you also able to define your custom "template", but it is not so easy, it requires you to know the Formly APIs -- how to define a custom template. But still Angular Formly is really good libaray for AngularJS to deal with complex form logic, a much cleaner and nicer way than control all the stuffs (template, error messages, validations...) by html.

 

So let's take an example first before explain some details stuff:

复制代码
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  ...
  template: `
    <div class="stock-inventory">
      <form [formGroup]="form">

        <div formGroupName="store">
          <input 
            type="text" 
            placeholder="Branch ID"
            formControlName="branch">
          <input 
            type="text" 
            placeholder="Manager Code"
            formControlName="code">
        </div>

      </form>
    </div>
  `
})
export class StockInventoryComponent {
  form = new FormGroup({
    store: new FormGroup({
      branch: new FormControl('B182'),
      code: new FormControl('1234')
    })
  })
}
复制代码

In the html, we have '[formGroup]', 'formGroupName', 'formControlName'.

The structure is like:
[formGroup]="form"

----formGroupName="store"

--------formControlName="branch"

--------formControlName="code"

 

In the Javascript, we define:

  form = new FormGroup({
    store: new FormGroup({
      branch: new FormControl('B182'),
      code: new FormControl('1234')
    })
  })

The structure is like:

FormGroup="form"

----FormGroup="store"

--------FormControl="branch"

--------FormControl="code"

 

So you can find that the html and JS code structure is the same. Just one question you may ask why:

<form [formGroup]="form">

and 

<div formGroupName="store">

One use [formGroup] and the other use "formGroupName"?

Well, the answer is really simple, because "[formGroup]=form", this "form" is an JS object. "store" is just an prop on the "form" object, so ALL the props-like stuff, we add "xxxName", like "formGroupName" and "formControlName". 

Now Angular is ready to take over the data bindings for the form.

 

Last thing I want to memtion in this post is passing "custom component" to the form.

So how to do that? Take previous example, we convert:

复制代码
        <div formGroupName="store">
          <input 
            type="text" 
            placeholder="Branch ID"
            formControlName="branch">
          <input 
            type="text" 
            placeholder="Manager Code"
            formControlName="code">
        </div>
复制代码

To a component.

 

Create a new component:

复制代码
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';

@Component({
  selector: 'stock-branch',
  styleUrls: ['stock-branch.component.scss'],
  template: `
    <div [formGroup]="parent">
      <div formGroupName="store">
        <input 
          type="text" 
          placeholder="Branch ID"
          formControlName="branch">
        <input 
          type="text" 
          placeholder="Manager Code"
          formControlName="code">
      </div>
    </div>
  `
})
export class StockBranchComponent {
  @Input()
  parent: FormGroup;
}
复制代码

We copy the html to the new component, we only add a extra Input "parent". So what it is ?

复制代码
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  ...
  template: `
    <div class="stock-inventory">
      <form [formGroup]="form">

        <stock-branch
          [parent]="form">
        </stock-branch>

      </form>
    </div>
  `
})
export class StockInventoryComponent {
  form = new FormGroup({
    store: new FormGroup({
      branch: new FormControl(''),
      code: new FormControl('')
    })
  })
}
复制代码

As you can see, we actually just pass down "form" object down to the child component. As re-structure [formGroup]-formGroupName-formControlName in the new component. 

 

So by now, hope it is clear for you how easy it is for Reactive form binding form to custom component. And hope you already find another tips: the chain partten: '[formGroup]-->formGroupName-->formControlName'

posted @   Zhentiw  阅读(965)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2016-03-20 [Angular 2] Using the @Inject decorator
2016-03-20 [WebStrom] Cannot detect file change to trigger webpack re-compile
2016-03-20 [TypeScript] Avoid any type
2016-03-20 [Angular 2] Injecting a Service
2016-03-20 [Angular 2] Event in deep
2015-03-20 [Javascript] Get Started with LeafletJS Mapping
2015-03-20 [Javascript] Gradient Fills on the HTML5 Canvas
点击右上角即可分享
微信分享提示