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

本文对比了Angular Formly与Angular 2+版本中的Reactive Forms,详细介绍了Reactive Forms如何将模板部分交还给HTML,专注于数据绑定和验证,并展示了如何轻松地将自定义组件与Reactive Forms结合使用。

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'

转载于:https://www.cnblogs.com/Answer1215/p/6583739.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值