【问题标题】:angular 6 warning for using formControlName and ngModel使用 formControlName 和 ngModel 的角度 6 警告
【发布时间】:2018-09-29 19:19:33
【问题描述】:

我最近将 angular 版本升级到 6-rc。我收到以下警告

看起来您在同一个表单字段上使用 ngModel 窗体控件名称。支持使用 ngModel 输入属性和 带有响应式表单指令的 ngModelChange 事件已被弃用 在 Angular v6 中,将在 Angular v7 中删除

有关这方面的更多信息,请在此处查看我们的 API 文档: https://angular.io/api/forms/FormControlName#use-with-ngmodel

它到底说了什么?该链接没有#use-with-ngmodel的任何片段

我想我需要删除 ngModel 并使用 formGroup 作为我的数据绑定对象。

【问题讨论】:

  • 你需要去next文档:next.angular.io/api/forms/FormControlName#use-with-ngmodel;虽然 v6 处于候选版本中,但文档仍然引用 v5。
  • 我们将ngModel 用于数据,formControl 用于验证。
  • @Akshay 我们做了同样的事情。将整个应用程序更改为从反应式表单控件手动获取/设置值似乎是一项艰巨的工作。
  • 在 Angular 6 响应式表单中没有 getter/setter 的快捷方式,就像在 C#.net 中一样,比如“string _myProperty { get; set; }”?如果您在一种形式中有大量输入,您的代码会不会变得难以阅读?
  • 我们所有使用 Angular 的人都越来越完全地脱离了真实的网络编程世界。

标签: angular angular-ngmodel angular-reactive-forms


【解决方案1】:

如果您现在正在寻找 Angular 6 文档,请使用 https://next.angular.io

https://next.angular.io/api/forms/FormControlName#use-with-ngmodel

所以你有 3 个选择:

  1. 使用响应式表单

  2. 使用模板驱动的表单

  3. 静音警告(不推荐)

    imports: [
      ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
    ]
    

【讨论】:

  • 天哪。改变语法和一直有效的东西有什么意义?我花了一天时间升级到 Angular 6 才发现这个。我注意到我的 onchange 选择事件没有触发。这是因为他们将这该死的语法从 onChange 更改为 selectionChange。真的很有用。
  • 还有更多:对于常见的输入(文本、文本区域、选择、复选框等),现在,Angular 通过响应式表单配置禁用(ing)强制 ...很好...你不能使用一直使用的disabled=true。最糟糕的是:如果你制作自己的 ui-components 库......Angular 可能不知道什么是禁用......很好......
  • 对于一个正在开发的全新应用,您会推荐以上 3 种替代方案中的哪一种?
  • @Stephane 我建议使用反应式表单
  • 如何在没有 ngmodel 的情况下获得反应形式的价值
【解决方案2】:

从 formGroup 中包含 formControlName 的每个字段中删除 [(ngModel)] 并在控制器类中设置值,如下简单 this.form.get('first').setValue('some value'); 不要关闭或显式静音警告

【讨论】:

  • 是的,但为了更好地理解,我从 Angular 文档中编写了一段代码
  • 感谢您尝试提高阅读和理解文档的示例
  • 那么你如何在没有 ngmodel 的情况下获得价值
  • @Flash, this.form.get('fieldName').value
【解决方案3】:

添加

[ngModelOptions]="{standalone: true}" 

您可以从 Angular 网站 https://angular.io/api/forms/NgModel 阅读更多内容

【讨论】:

  • 我认为很多人对 Angular 弃用支持 ngModel 以与 formControlName 一起使用而不是完全弃用 ngModel 的事实感到困惑。
  • 这是否意味着模板驱动的表单将消失,人们应该改用反应式表单?
【解决方案4】:

所以我在尝试在mat-select 中显示用户头像时偶然发现了这一点:

<mat-form-field [formGroup]="assignedToFormGroup">
<mat-select placeholder="Assign to" [(ngModel)]="assignedTo" formControlName="assignTo">
  <mat-select-trigger>
    <img style="vertical-align:middle;" aria-hidden
      src="{{assignedToFormGroup.controls['assignTo'].value.photoUrl}}" height="20" />
    <span>@{{assignedToFormGroup.controls['assignTo'].value.userName}}</span>
  </mat-select-trigger>
  <!-- {{user.userName}} -->
  <mat-option *ngFor="let user of members" [value]="user">
    <img style="vertical-align:middle;" aria-hidden src="{{user.photoUrl}}" height="20" />
    <span>@{{user.userName}}</span>
  </mat-option>
</mat-select>

在控制器中,formGroup 是这样定义的:

public assignedToFormGroup: FormGroup;

我听从了 Sohail 的建议,并从我的 HTML 代码中删除了 [(ngModel)]

<mat-form-field [formGroup]="assignedToFormGroup">
<mat-select placeholder="Assign to" formControlName="assignTo">
  <mat-select-trigger>
    <img style="vertical-align:middle;" aria-hidden
      src="{{assignedToFormGroup.controls['assignTo'].value.photoUrl}}" height="20" />
    <span>@{{assignedToFormGroup.controls['assignTo'].value.userName}}</span>
  </mat-select-trigger>
  <!-- {{user.userName}} -->
  <mat-option *ngFor="let user of members" [value]="user">
    <img style="vertical-align:middle;" aria-hidden src="{{user.photoUrl}}" height="20" />
    <span>@{{user.userName}}</span>
  </mat-option>
</mat-select>

打开页面时出现错误 - 我尝试从 null 加载 photoUrl 和 userName,因为通过删除 [(ngModel)] 我还删除了 mat-select 中的默认选择。

所以我修改了我的控制器以执行以下操作: 1.构造函数:

this.assignedToFormGroup.controls['assignTo'].setValue({photoUrl: '', userName: ''});
  1. 我保存表单的按钮操作 - 添加了以下行:

    let assignedTo = this.assignedToFormGroup.controls['assignTo'].value;

这确实有效。现在我在页面加载时设置默认选择并在提交表单时读取选定的值。 我知道这不是最好和最漂亮的解决方案,但我想我会分享它 - 可能是更好的解决方案的一个很好的起点。

【讨论】:

    【解决方案5】:

    结合 Rxjs 使用 formControl(reactive Forms) 更直接,因此 Angular 团队改变了使用它。

    修改html文件

    <!-- [ngModel]='model' (ngModelChange)='changed($event)' -->
    

    [formControl]="myControl"
    

    修改ts文件

    model: string;
      modelChanged: Subject<string> = new Subject<string>();
    
      changed(text: string) {
          this.modelChanged.next(text);
      }
      this.modelChanged.pipe(
          .subscribe(model => this.postErrorMessage = model);
    

    this.myControl.valueChanges.pipe(
          .subscribe(model => this.postErrorMessage = model);
    

    【讨论】:

      猜你喜欢
      • 2021-07-07
      • 1970-01-01
      • 2019-07-28
      • 1970-01-01
      • 2019-01-26
      • 2020-01-03
      • 2018-11-20
      • 2019-02-01
      • 1970-01-01
      相关资源
      最近更新 更多