Angular2错误:没有将“ exportAs”设置为“ ngForm”的指令


109

我在RC4上并且遇到错误由于我的模板,没有将“ exportAs”设置为“ ngForm”的指令

<div class="form-group">
        <label for="actionType">Action Type</label>
        <select
            ngControl="actionType" 
      ===>  #actionType="ngForm" 
            id="actionType" 
            class="form-control" 
            required>
            <option value=""></option>
            <option *ngFor="let actionType of actionTypes" value="{{ actionType.label }}">
                {{ actionType.label }}
            </option>
        </select> 
    </div>

boot.ts:

import {disableDeprecatedForms, provideForms} from '@angular/forms'; 

 import {bootstrap} from '@angular/platform-browser-dynamic';
 import {HTTP_PROVIDERS, Http} from '@angular/http';
 import {provideRouter} from '@angular/router';

import {APP_ROUTER_PROVIDER} from './routes';

import {AppComponent} from './app.component';

bootstrap(AppComponent, [ disableDeprecatedForms(), provideForms(), APP_ROUTER_PROVIDER, HTTP_PROVIDERS]);

///这是我的DropdownList:

<fieldset ngControlGroup="linkedProcess" >
                     <div ngControlGroup="Process" >
                         <label>Linked Process</label>
                          <div class="form-group">       
        <select 
            ngModel
            name="label" 
            #label="ngModel" 
            id="label" 
            class="form-control" required
            (change)="reloadProcesse(list.value)" 
            #list>
            <option value=""></option>
            <!--<option value=`{{ActionFormComponent.getFromString('GET'')}}`></option>-->                 
            <option *ngFor="let processus of linkedProcess?.processList?.list; let i = index" 
            value="{{ processus[i].Process.label}}">
                {{processus.Process.label}}
            </option>
        </select> 
        </div>
     </div>

//我的组件ts:

我用这样的旧形式表示它:

 categoryControlGroups:ControlGroup[] = [];
     categories:ControlArray = new ControlArray(this.categoryControlGroups);

现在我正在这样做:

categoryControlGroups:FormGroup[] = [];
     categories:FormArray = new FormArray(this.categoryControlGroups);

您认为这是导致问题的原因?


您使用什么版本?您是否填写表格?
acdcjunior 2016年

Answers:


98

2.0.0.rc6开始

形式:已弃用provideForms()disableDeprecatedForms()功能已删除。请导入FormsModuleReactiveFormsModule@angular/forms代替。

简而言之:

因此,添加到您的app.module.ts或等效项中:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; // <== add the imports!
 
import { AppComponent }  from './app.component';
 
@NgModule({
  imports: [
    BrowserModule,
    FormsModule,                               // <========== Add this line!
    ReactiveFormsModule                        // <========== Add this line!
  ],
  declarations: [
    AppComponent
    // other components of yours
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

如果没有这些模块之一,可能会导致错误,包括您面临的模块:

无法绑定到“ ngModel”,因为它不是“ input”的已知属性。

无法绑定到“ formGroup”,因为它不是“ form”的已知属性

没有将“ exportAs”设置为“ ngForm”的指令

如果你有疑问的时候,你可以同时提供FormsModuleReactiveFormsModule在一起,但他们是全功能的分开。当您提供这些模块之一时,该模块的默认表单指令和提供程序将在整个应用范围内供您使用。


旧表格使用ngControl

如果确实有这些模块@NgModule,则可能您正在使用旧的指令,例如ngControl,这是一个问题,因为ngControl新形式中没有。它或多或少 * 被代替ngModel

举例来说,相当于<input ngControl="actionType"><input ngModel name="actionType">,这样的变化,在您的模板。

同样,ngForm现在不再是控件的导出ngModel。因此,在您的情况下,请替换#actionType="ngForm"#actionType="ngModel"

因此,生成的模板应为(===>更改后的):

<div class="form-group">
    <label for="actionType">Action Type</label>
    <select
  ===>  ngModel
  ===>  name="actionType" 
  ===>  #actionType="ngModel" 
        id="actionType" 
        class="form-control" 
        required>
        <option value=""></option>
        <option *ngFor="let actionType of actionTypes" value="{{ actionType.label }}">
            {{ actionType.label }}
        </option>
    </select> 
</div>

*或多或少是因为并非的所有功能都已ngControl移至ngModel。有些刚刚被删除或现在有所不同。name属性就是一个例子,您现在拥有的就是这种情况。


谢谢您的回答,当我更改它时出现错误无法分配给引用或变量,它对您说了些什么?
2016年

嗯..可能在其他地方。你有什么<input>里面*ngFor?(可能不会工作,但试试这个,如果此消息消失告诉我:<option *ngFor="let actionType of actionTypes; let i = index" value="{{ actionTypes[i].label }}"> {{ actionTypes[i].label }} </option>
acdcjunior

内是否有任何<input> *ngFor
acdcjunior

尝试将里面的变量重命名为*ngFor,而不是actionType
acdcjunior

不,我没有,但是我有一个要迭代的选择下拉列表,我不知道这是否是错误的根源,请看看我更新的问题...
安娜

61

我遇到了同样的问题。我错过了app.module.ts中的表单模块导入标签

import { FormsModule } from '@angular/forms';

@NgModule({
    imports: [BrowserModule,
        FormsModule
    ],

2
感谢此,它工作正常,但应该是app.module.ts而不是app.module.component.ts
Salim

即使我已经将FormsModule导入已放入我的app.module中,这对我也不起作用
emirhosseini

9

我有同样的问题,可以通过将FormsModule添加到.spec.ts来解决:

import { FormsModule } from '@angular/forms';

然后将导入添加到beforeEach:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [ FormsModule ],
    declarations: [ YourComponent ]
  })
.compileComponents();
}));

5

如果您得到的是:

错误:模板解析错误:

没有将“ exportAs”设置为“ ngModel ”的指令

在github中将报告为错误,然后可能不是错误,因为您可能会:

  1. 出现语法错误(例如,额外的括号:)[(ngModel)]]=,或者
  2. 混合活性形式的指令,例如formControlName与所述ngModel指令。这个“在Angular v6中已被弃用,在Angular v7中将被删除”,因为这混合了两种形式的策略,使其成为:
  • 看起来好像ngModel正在使用实际的伪指令,但实际上,它是ngModel在反应形式伪指令上命名的输入/输出属性,它只是近似(部分)其行为。具体来说,它允许获取/设置值并拦截值事件。然而,一些ngModel的其他功能 -就像推迟更新ngModel Option或导出指令- 根本不起作用(...)

  • 这种模式混合了模板驱动和反应形式策略, 我们通常不建议这样做,因为它没有利用这两种策略的全部优势。(...)

  • 要在v7之前更新代码,您需要决定是坚持使用响应式表单指令(以及使用响应式表单模式获取/设置值)还是切换到模板驱动的指令

当您有这样的输入时:

<input formControlName="first" [(ngModel)]="value">

它将在浏览器的控制台中显示有关混合格式策略的警告:

看起来您使用ngModel的表单字段与formControlName

但是,如果将ngModelas作为值添加到引用变量中,则示例:

<input formControlName="first" #firstIn="ngModel" [(ngModel)]="value">

然后触发以上错误,并且未显示有关策略混合的警告。


4

在我来说,我不得不添加FormsModuleReactiveFormsModuleshared.module.ts过:

(感谢@Undrium的代码示例):

import { NgModule }                                 from '@angular/core';
import { CommonModule }                             from '@angular/common';
import { FormsModule, ReactiveFormsModule }         from '@angular/forms';

@NgModule({
  imports:      [
    CommonModule,
    ReactiveFormsModule
  ],
  declarations: [],
  exports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule
  ]
})
export class SharedModule { }

这解决了我的问题。仅将其添加到app.module中是不够的
emirhosseini

3

我遇到了这个问题,我意识到自己没有将组件绑定到变量。

已变更

<input #myComponent="ngModel" />

<input #myComponent="ngModel" [(ngModel)]="myvar" />


2

Angular2现在使用表格的正确方法是:

<form  (ngSubmit)="onSubmit()">

        <label>Username:</label>
        <input type="text" class="form-control"   [(ngModel)]="user.username" name="username" #username="ngModel" required />

        <label>Contraseña:</label>
        <input type="password" class="form-control"  [(ngModel)]="user.password" name="password" #password="ngModel" required />


    <input type="submit" value="Entrar" class="btn btn-primary"/>

</form>

旧的方式不再有效


1

当尝试将反应形式和模板形式方法结合起来时,也意识到了这个问题。我有#name="ngModel"[formControl]="name"在相同的元素。删除其中一个解决了该问题。同样不是说,如果您使用的#name=ngModel话,还应该具有诸如this的属性[(ngModel)]="name",否则,您仍然会得到错误。这也适用于角度6、7和8。


0

检查您是否同时ngModel and name选择了这两个属性。另外Select是一个表单组件,而不是整个表单,因此,本地引用的更多逻辑声明将是:

<div class="form-group">
    <label for="actionType">Action Type</label>
    <select
            ngControl="actionType" 
      ===>  #actionType="ngModel"
            ngModel    // You can go with 1 or 2 way binding as well
            name="actionType"
            id="actionType" 
            class="form-control" 
            required>
            <option value=""></option>
            <option *ngFor="let actionType of actionTypes" value="{{ actionType.label }}">
                {{ actionType.label }}
            </option>
        </select> 
    </div>

还有一件重要的事情是确保FormsModule在模板驱动方法或ReactiveFormsModule响应式方法的情况下导入。或者,您也可以同时导入两者。


0

如果ngModule在输入中不起作用,请尝试...删除双引号ngModule

喜欢

<input #form="ngModel" [(ngModel)]......></input>

而不是上面

<input #form=ngModel [(ngModel)]......></input> try this

-1

我有这个问题,因为我的模板在[[ngModel)]]附近有错字。额外的支架。例:

<input id="descr" name="descr" type="text" required class="form-control width-half"
      [ngClass]="{'is-invalid': descr.dirty && !descr.valid}" maxlength="16" [(ngModel)]]="category.descr"
      [disabled]="isDescrReadOnly" #descr="ngModel">
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.