Angular2如果在form标签中使用ngModel,必须设置name属性或者form属性。

289

我从Angular 2中得到了这个错误:

core.umd.js:5995 EXCEPTION: Uncaught (in promise): Error: Error in app/model_exposure_currencies/model_exposure_currencies.component.html:57:18 caused by: 如果在form标签内使用ngModel,必须设置name属性或将表单控件在ngModelOptions中定义为“独立的”。

示例1:

<input [(ngModel)]="person.firstName" name="first">

示例 2:

<input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}"> 
<td *ngFor="let lag of ce.lags">
    <div class="form-group1">
        <input name="name" [(ngModel)]="lag.name" [ngModelOptions]="{standalone: true}"  class="form-control" pattern="[0-9]*(\.[0-9]+)?" required>
    </div>
</td>

这是我使用表单标签的方式:

<form #f="ngForm" (ngSubmit)="onSubmit()">

7
考虑将其中一个答案评为正确答案。 - G. Stoynev
15个回答

563

如果使用ngForm,所有具有[(ngModel)]=""的输入字段必须具有一个带值的name属性。

<input [(ngModel)]="firstname" name="something">

独立使用

通过设置[ngModelOptions]="{standalone: true}",就告诉Angular忽略表单和/或ngForm,请只将其绑定到firstname变量。

然而,如果不小心使用了form标签(像我有时候一样),将form更改为div是另一个选择(前提是您的样式不需要form标签)。


2
在 https://angular.io/docs/ts/latest/api/forms/index/NgModel-directive.html 中搜索“name属性”。 - Thyagarajan C
2
从Angular 5文档(https://angular.io/guide/forms)中得知:“在使用[(ngModel)]与表单结合时,定义name属性是必需的。” - elshev
2
适用于Angular 7! - coderpc
2
这个答案帮了我两次,但为什么名称字段很重要? - saber tabatabaee yazdi
4
请允许我翻译您的内容:“我想补充一点,只有在ngModel出现在name之前时才能起作用。” - Ronald Abellano
显示剩余5条评论

64

作为每个开发者的共同习惯,不去阅读完整的错误信息,只看第一行便开始寻找别人的答案。我也是其中之一,这也是我在这里的原因。

错误信息很清晰地指出:

Example 1: <input [(ngModel)]="person.firstName" name="first">
Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">

我们需要了解这个错误的更多信息吗?

使用任何一种选项,一切都会顺利运作。


40
解释每个选项的含义和影响会很有帮助——随意选择其中一个并不是一个好主意。 - Michael
1
这里有一个关于 [ngModelOptions]="{standalone: true} 的好解释:https://dev59.com/KVoT5IYBdhLWcg3wnQn9#38368261。在我的情况下,当我有一个嵌套数组的 *ngFor* 时,我得到了可怕的 ngModel is used within a form tag, either the name attribute must... 错误。模型绑定没问题,但模板出错了。"Example 1" 不可能 工作;"Example 2" 是完美的。 - FoggyDay
2
这个答案在同一周内帮助了我两次(显然第一次没有留下印象);) - Jay Cummins
正如答案中所提到的,解决方案就在错误本身,而且我第一眼看不出来,也正如答案中再次提到的 :) 谢谢,它起作用了。 - Siva Makani

39

在我的情况下,错误是因为以下 HTML 标记中还存在一行没有 name 属性。

<form id="form1" name="form1" #form="ngForm">
    <div class="form-group">
        <input id="input1" name="input1" [(ngModel)]="metaScript" />
        ... 
        <input id="input2" [(ngModel)]="metaScriptMessage"/>
    </div>
</form>

但是浏览器仍然报告第一行有错误,如果这两个元素之间还有其他元素的话,就很难发现错误的源头。 Chrome DevTools 展示错误的屏幕截图


34

需要同时使用这两个属性,并检查所有表单元素是否有“name”属性。如果您正在使用表单提交的概念,则必须这样做,否则只需使用div标记代替表单元素即可。

<input [(ngModel)]="firstname" name="something">

20

我注意到Chrome开发者工具有时仅以波浪形红线标出第一个元素,即使它已正确设置名称。这让我困惑了一段时间。

无论哪个字段被波浪形下划线标出,必须确保在包含ngModel的表单中为每个元素都添加名称


哇!谢谢!那花了我一段时间! - Jens Mander

19

当您清晰地查看控制台时,它会给出两个示例。实现其中任何一个。

<input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone:true}">

或者

<input [(ngModel)]="person.firstName" name="first">

2
不要随便选择,你必须理解自己在做什么。 - User2585
@User2585,我同意你的观点,但你能否详细解释一下它们之间的区别呢?我发现每个人都建议使用“name”属性,但没有人解释使用“name”属性的具体意义是什么? - Prajjwal Gupta
1
如果您想使ngModel成为ngForm的一部分,则需要为它(表单控件)指定一个名称,然后表单值将具有带有给定名称(在此示例中为“first”)和输入值的属性。如果由于某种原因您不想使ngModel成为ngForm的一部分,则可以指定[ngModelOptions] =“ {standalone:true}”,然后您就不需要名称。 - User2585

12

修复起来相当容易。

对于我来说,我们在表单中有多个输入。我们需要找出导致错误的输入/行,并简单地添加name属性。这为我解决了问题:

之前:

<form class="example-form">

    <mat-form-field appearance="outline">

      <mat-select placeholder="Select your option" [(ngModel)]="sample.stat"> <!--HERE -->

          <mat-option *ngFor="let option of actions" [value]="option">{{option}</mat-option>
      </mat-select>
    </mat-form-field>

    <mat-form-field appearance="outline">
      <mat-label>Enter number</mat-label>

      <input id="myInput" type="text" placeholder="Enter number" aria-label="Number"
        matInput [formControl]="myFormControl" required [(ngModel)]="number">  <!--HERE -->

    </mat-form-field>

    <mat-checkbox [(ngModel)]="isRight">Check!</mat-checkbox> <!--HERE -->

  </form>

之后: 我只是为 selectcheckbox 添加了 name 属性,问题就解决了。具体如下:

<mat-select placeholder="Select your option" name="mySelect" 
  [(ngModel)]="sample.stat"> <!--HERE: Observe the "name" attribute -->

<input id="myInput" type="text" placeholder="Enter number" aria-label="Number"
        matInput [formControl]="myFormControl" required [(ngModel)]="number">  <!--HERE -->

<mat-checkbox name="myCheck" [(ngModel)]="isRight">Check!</mat-checkbox> <!--HERE: Observe the "name" attribute -->

你看到已经添加了name属性。它不一定要与你的ngModel名称相同。只需提供name属性即可解决问题。


4

对于那些不惊慌于错误信息本身,只是搜索“为什么来自这里的例子不起作用(即在输入字段中键入文本时不会发生动态过滤)”的解释的人们:在输入字段中添加name参数之前,它将无法正常工作。没有任何迹象表明管道不起作用,但错误消息指向了这个主题,并根据接受的答案进行修复,则动态过滤器可以正常工作。


4

试试这个...

<input type="text" class="form-control" name="name" placeholder="Name" required minlength="4" #name="ngModel" ngModel>
<div *ngIf="name.errors && (name.dirty || name.touched)">
    <div [hidden]="!name.errors.required" class="alert alert-danger form-alert">
        Please enter a name.
    </div>
    <div [hidden]="!name.errors.minlength" class="alert alert-danger form-alert">
        Enter name greater than 4 characters.
    </div>
</div>

4
你需要在你的page.ts文件中导入{ NgForm } from @angular/forms;
HTML代码:
<form #values="ngForm" (ngSubmit)="function(values)">
 ...
 <ion-input type="text" name="name" ngModel></ion-input>
 <ion-input type="text" name="mail" ngModel></ion-input>
 ...
</form>

在您的Page.ts中,实现用于操作表单数据的函数:
function(data) {console.log("Name: "data.value.name + " Mail: " + data.value.mail);}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接