美文网首页
[日记]Angular Form

[日记]Angular Form

作者: 刘开心_8a6c | 来源:发表于2019-03-11 23:09 被阅读0次

简单记录一下最近学习的Angular Form相关知识,并实现一个「编辑-显示」Demo。

Form简介

Angular包含两种类型的form,分别是Reactive formsTemplate-driven forms。两者异同以及适用场景在这里有详细介绍。

Reactive forms与Template-driven forms在实现层面最大的不同在于:

  • Reactive forms是在html元素中添加[formControl] directive,然后在ts文件中显式地新建一个实例,如下:

html:

<input type="text" [formControl]="xxxControl">

typescript:

...
export class XComponent {
  xxxControl = new FormControl('I am an init value');
}
  • Template-driven forms是在html中添加[(ngModel)],ngModel的名字与类属性名相同,FormControl的实例被隐式创建。

html:

<input type="text" [(ngModel)]="xxxControl">

typescript:

...
export class XComponent {
  xxxControl = 'I am an init value';
}

Angular的一大特点就是view与model的双向绑定,也就是说html的DOM元素与对应的model始终是同步的。页面input值改变,对应的xxxControl值也改变。

如果想通过model更改view,对于Reactive forms,只需要this.xxxControl.setValue('new value');对于Template forms,只需要this.xxxControl = 'new value',view上的显示就会随之更改。

Reactive forms keep the data model pure by providing it as an immutable data structure. Each time a change is triggered on the data model, the FormControl instance returns a new data model rather than updating the existing data model.

Template-driven forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template.

了解到这些,就可以实现一个简单的demo。

Demo实现

这个Demo最终的效果是:

  • 第一次进入页面,显示两个标签(其实被disabled 的input),分别是姓名与星座。
    init
  • 点击被disabled的input,会出现apply按钮与cancel按钮, 同时input变为可编辑状态,用户可以随意输入姓名与星座。
    editmode
    • 点击apply,input被disabled,同时显示修改后的值


      click apply
    • 点击cancel,input仍然显示上次显示的值。


      click cancel

分析

  1. 页面上有两套控件,分别是一组可以与用户交互的input,以及一组被当作标签使用的disabled input。可以使用一个变量editMode控制显示哪一组input,如果是可编辑的,则显示可交互的input,否则显示disabled input;
  2. 初始状态显示的是disabled input,包括name与zodiac sign两个input,两者的默认值可以内置在代码中,或从其他地方读取;而可交互的那组默认值则设置为从disabled input上取值,name与zodiac sign分别取对应的值;
  3. 点击apply后,disabled input上的值设置为可交互的input上的值;
  4. 点击cancel后,可交互的 input上的值设置从disabled input上的值。

实现

  1. 如果用Reactive form, 则在app.module.tsimports array中加入ReactiveFormsModule;如果用Template-driven form,则在importsarray中加入FormsModule.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    FormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. 写html页面

app.component.html

<div *ngIf="editMode">
  name:
  <input  type="text" [formControl]="nameControl"/>
  zodiac sign:
  <input  [formControl]="zodiacSignControl"/>
  <div>
    <button (click)="apply()">apply</button>
    <button (click)="cancel()">cancel</button>
  </div>
 
</div>

<div *ngIf="!editMode" (click)="onClick()">
name:
<input disabled [formControl]="showNameControl"/>
zodiac sign:
<input disabled [formControl]="showZodiacSignControl"/>
</div>
  1. 写逻辑

app.component.ts

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  editMode = false;
  showNameControl = new FormControl('Tim');
  showZodiacSignControl = new FormControl('Lion');
  nameControl = new FormControl(this.showNameControl.value);
  zodiacSignControl = new FormControl(this.showZodiacSignControl.value);

  apply() {
    this.editMode = false;
    this.showNameControl.setValue(this.nameControl.value);
    this.showZodiacSignControl.setValue(this.zodiacSignControl.value);
  }

  cancel() {
    this.nameControl.setValue(this.showNameControl.value);
    this.zodiacSignControl.setValue(this.showZodiacSignControl.value);
  }

  onClick() {
    this.editMode = true;
  }
}

常见错误

  1. can't bind to 'ngModel' since it isn't a known property of 'input' or can't bind to 'formControl' since it isn't a known property of 'input'
  • 可能忘记在app.module.tsimportsarray中加入相应的module

repo: https://github.com/LiuKaixinHappy/angular-form-demo

好的angular form博客:

相关文章

网友评论

      本文标题:[日记]Angular Form

      本文链接:https://www.haomeiwen.com/subject/ptpipqtx.html