Angular 6升级后移除组件中ngModel的方法
解决Angular 6中同时使用ngModel与formControl的弃用警告问题
我来帮你搞定这个Angular的弃用警告问题。当你在响应式表单里同时用formControl和ngModel时,Angular确实会抛出这个警告,而且Angular 7之后就彻底不支持这种写法了。咱们一步步把ngModel去掉,同时保持原有功能:
1. 移除模板中的ngModel绑定
首先直接把模板里的[(ngModel)]="value"删掉就行,修改后的input标签如下:
<input type="text" id="{{id}}" name="{{name}}" [formControl]="ctrl" appPfMaskCpf="999.999.999-99" placeholder="{{placeholder}}" class="form-control">
2. 调整组件类里的值管理逻辑
原来你用value变量来存储输入值,现在直接通过formControl的value属性来访问就好:
- 如果需要初始化输入框的值,不要给
value赋值,而是在创建FormControl的时候传入初始值:import { FormControl } from '@angular/forms'; // 组件类中初始化FormControl,替换原来的value变量初始化 ctrl = new FormControl(yourInitialValue || ''); - 之后在组件里需要获取输入值时,用
this.ctrl.value代替原来的this.value。
3. 重构CPF验证逻辑(替换flagCpfInvalido)
你原来用flagCpfInvalido来控制错误提示,现在可以改成两种方式,推荐第二种更符合Angular响应式表单的最佳实践:
方式一:监听FormControl的值变化
如果想保留类似原来的flagCpfInvalido变量,可以通过监听valueChanges来更新它:
import { FormControl } from '@angular/forms'; import { Subscription } from 'rxjs'; export class YourComponent implements OnInit, OnDestroy { ctrl = new FormControl(''); flagCpfInvalido = false; private valueSub: Subscription; ngOnInit() { // 监听输入值变化,更新验证状态 this.valueSub = this.ctrl.valueChanges.subscribe(inputValue => { // 先去掉掩码里的非数字字符,再做验证 const cleanedCpf = inputValue.replace(/\D/g, ''); this.flagCpfInvalido = this.checkCpfInvalid(cleanedCpf); }); } ngOnDestroy() { // 记得取消订阅,避免内存泄漏 this.valueSub.unsubscribe(); } // 你的CPF验证逻辑实现 private checkCpfInvalid(cpf: string): boolean { if (cpf.length !== 11) return true; // 这里补充你原来的其他验证规则,比如校验位验证等 return false; } }
模板里的错误提示部分可以保留原来的逻辑,因为flagCpfInvalido还是会正确更新。
方式二:使用自定义验证器(推荐)
更规范的做法是把CPF验证做成自定义验证器,集成到FormControl的验证体系里,这样不需要手动维护flagCpfInvalido变量:
首先创建一个自定义验证器函数:
import { ValidatorFn, AbstractControl } from '@angular/forms'; // CPF自定义验证器 export function cpfValidator(): ValidatorFn { return (control: AbstractControl): { [key: string]: any } | null => { const inputValue = control.value; if (!inputValue) return null; // 空值不触发验证 const cleanedCpf = inputValue.replace(/\D/g, ''); // 这里写你的CPF验证逻辑 const isValid = cleanedCpf.length === 11 && /* 补充校验位等验证规则 */; return isValid ? null : { invalidCpf: true }; }; }
然后在组件里给FormControl添加这个验证器:
import { FormControl } from '@angular/forms'; import { cpfValidator } from './path-to-your-validator'; export class YourComponent { // 初始化FormControl时添加验证器 ctrl = new FormControl('', [cpfValidator()]); }
最后修改模板里的错误提示,根据FormControl的验证状态来显示:
<div *ngIf="ctrl.hasError('invalidCpf') && ctrl.touched"> <small class="text-danger"> CPF inválido. </small> <br> </div>
这里用ctrl.touched可以确保用户和输入框交互后才显示错误,体验更好。
这样修改之后,不仅彻底移除了ngModel,解决了弃用警告,还让表单逻辑更符合Angular响应式表单的设计理念,代码也更简洁可维护。
内容的提问来源于stack exchange,提问作者Rafael Augusto
相关产品推荐
相关产品推荐

