删除 ngModel 后如何传递数据?

How to pass data, when ngModel is removed?

我正在使用 MatDialog,我需要使用输入字段的值并验证它。

<input matInput [(ngModel)]="name" formControlName="name">
data: {name: this.name, animal: this.animal},

嗯,这给了我这个警告:

It looks like you're using ngModel on the same form field as formControlName. Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and will be removed in a future version of Angular.

For more information on this, see our API docs here:
https://angular.io/api/forms/FormControlName#use-with-ngmodel

现在我改成了:

<input matInput formControlName="name">
data: {name: this.formMain.get('name')?.value, animal: this.animal},

这适用于我的 name 输入字段。但我有另一个输入字段 (animal),它位于对话框内,如下所示:

<input matInput [(ngModel)]="data.animal" formControlName="animal">

现在当我删除 ngModel 时,我该如何让它工作?

查看 StackBlitz 上的完整代码。

这是关于两个不同的主题:-

  1. 响应式表单与模板驱动表单
  2. 将数据传递给 MatDialogRef

有很多关于响应式表单和使用“formControlName”而不是 [(ngModel])

的信息

https://blog.angular-university.io/introduction-to-angular-2-forms-template-driven-vs-model-driven/

将数据传递给 MatDialogRef 可能会造成混淆,但您的对话框组件中应该有这样的构造函数:-

  constructor(public dialogRef: MatDialogRef<SomeDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any) {}

然后在您的代码中启动此对话框:-

// some code to get the correct animal and set 'this.animal' ??
this.dialog.open(SomeDialogComponent, {
      data: { name: this.formMain.get('name')?.value, animal: this.animal }
    });

因此在您的对话框组件中,您可以通过注入的值引用“接收到的”数据。

  ngOnInit(): void {
    console.log(this.data?.animal);
  }

好吧,让我们看看:)

我们有不同的可能性来获取 angular 中的输入文本值。 目前您正在使用两种方式的数据绑定,这意味着 ngModel 周围的 [] 是从 TypeScript 值到 HTML 模板的路径。 () 反之亦然,它根据您在 HTML.

中所做的更改更新 TypeScript 中的值

所以我们当然可以删除 ngModel 并使用类似以下内容手动将变量的值输入到输入中:

<input [value]="data.animal" #form>

我们仍然错过了另一种方式,所以我们可能应该添加一个按钮或类似的按钮,并在 html 发生变化后使用(单击)事件更新 TypeScript 文件中的变量。

<button (click)="updateValue(form.value)">Clickme</button>

创建函数后,这应该可以正常工作。

当然还有另一种可能使用ViewChild 引用。 所以首先像以前一样定义引用。

<input type="text" id="form" name="form" #form>

然后在 TypeScript 文件中我们声明对 ViewChild 的引用。

@ViewChild('form', {static: true}) formElement: ElementRef;
mydata:string="";
constructor(formElement: ElementRef){
  this.formElement = formElement;
}

然后 mydata 将包含在输入字段中输入的字符串。该值也可以在输入字段中再次设置为默认值。

您也可以将原生 html API 与 document.getElementById 之类的东西一起使用并获取输入的值,但我会在这一点上忽略这一点,因为我想其他可能性足够方便。

如果你想使用 formControlName 也有可能。

<form [formGroup]="nameForm">
<p>
   <input type="text" id="name" name="name" formControlName="name">
</p>
</form>

并且在 TypeScript 文件中我们可以像这样访问输入。

constructor( private formBuilder: FormBuilder) {
 this.nameForm = this.formBuilder.group({
   name: ''
 });
}
onClick() {
  this.myusername=this.nameForm.get('name')?.value;
  console.log('it does nothing', this.nameForm.get('name'));
}

或者您可以只在输入上使用模糊事件并使用 $event 管道发送值。

<p><input type="text" (blur)="blurEvent($event)">

将像

一样访问
blurEvent(event: any) {
  this._value = event.target.value;
}

希望这对您有所帮助。

简短说明

您只是将不存在的数据传递给 MatDialog 的关闭输出。

您在模板中提到的 data.animal 只是 调用者 发送到 的数据 MatDialog。这就是它被注入其中的原因。在注射点,你的答案还不存在。您将输入字段绑定到 FormGroup,而不是 MAT_DIALOG_DATA

在原始代码中 ngModel 直接绑定到 MAT_DIALOG_DATA,所以这不是问题。

选项 1:从表单而不是 MatDialog 传递数据

你只需要改变这一行,在dialog-overview-example-dialog.html:

<button mat-button [mat-dialog-close]="formDialog.value.animal" cdkFocusInitial>

就这么简单,你们非常亲密。 这是对 Stackblitz 的修复。

选项 2:在 MatDialog 上设置数据

您还可以收听表单上的更改并相应地在 MatDialog 上设置数据值,如下所示:

this.formDialog.valueChanges.subscribe(val => {
      this.data.animal = val.animal;
});

这也是 Stackblitz 上的一个例子。

选项 3:创建您自己的函数

在模板中:

<button mat-button (click)="send()" cdkFocusInitial>

在打字稿中:

send(): void {
    this.dialogRef.close(this.formDialog.value.animal);
}

还有另一个最后的 Stackblitz 例子给你。