Błąd Angular2: nie ma dyrektywy z ustawieniem „exportAs” na „ngForm”

109

Jestem na RC4 i otrzymuję błąd Nie ma dyrektywy z "exportAs" ustawionym na "ngForm" z powodu mojego szablonu:

<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]);

/// więc oto moja lista rozwijana:

<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>

// mój ts komponentu:

przedstawiałem to w starych formach, takich jak ta:

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

a teraz robię to:

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

myślisz, że to przyczyna problemu ??

Ania
źródło
Jakiej wersji używasz? Czy wyskoczyłeś z formularzy?
acdcjunior

Odpowiedzi:

98

Od 2.0.0.rc6 :

formularze : przestarzałe provideForms()i disableDeprecatedForms()funkcje zostały usunięte. Zamiast tego zaimportuj FormsModulelub ReactiveFormsModulez @angular/forms.

W skrócie:

Więc dodaj do swojegoapp.module.ts lub odpowiednika:

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 { }

Brak jednego z tych modułów może prowadzić do błędów, w tym tego, z którym się spotykasz:

Nie można powiązać z „ngModel”, ponieważ nie jest to znana właściwość „input”.

Nie można powiązać z „formGroup”, ponieważ nie jest to znana właściwość „form”

Nie ma dyrektywy z opcją „exportAs” ustawioną na „ngForm”

Jeśli masz wątpliwości, możesz podać oba te FormsModuleelementy ReactiveFormsModulerazem, ale są one w pełni funkcjonalne osobno. Po udostępnieniu jednego z tych modułów domyślne dyrektywy formularzy i dostawcy z tego modułu będą dostępne dla całej aplikacji.


Stare Formularze używają ngControl?

Jeśli masz te moduły u siebie @NgModule, być może używasz starych dyrektyw, takich jak ngControl, co jest problemem, ponieważ nie ma ich ngControlw nowych formularzach. Został zastąpiony mniej więcej * przez ngModel.

Na przykład odpowiednik to <input ngControl="actionType">jest <input ngModel name="actionType">, więc zmień to w swoim szablonie.

Podobnie nie ngFormma już eksportu kontroli, jest nim teraz ngModel. Tak więc, w przypadku zastąpienia #actionType="ngForm"z #actionType="ngModel".

Zatem wynikowy szablon powinien wyglądać następująco ===>:

<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>

* Mniej więcej dlatego, że nie wszystkie funkcje ngControlzostały przeniesione do ngModel. Niektóre zostały właśnie usunięte lub są teraz inne. Przykładem jest nameatrybut, ten sam przypadek, który masz teraz.

acdcjunior
źródło
dziękuję za odpowiedź, kiedy to zmieniłem, pojawia się błąd Nie można przypisać do referencji lub zmiennej, czy to coś do Ciebie mówi ??
Anna
Hmm ... to może być gdzieś indziej. Czy masz jakieś w <input>środku *ngFor? (Prawdopodobnie nie będzie działać, ale spróbuj to i powiedz mi, czy komunikat zniknie: <option *ngFor="let actionType of actionTypes; let i = index" value="{{ actionTypes[i].label }}"> {{ actionTypes[i].label }} </option>)
acdcjunior
Czy masz jakieś <input> wewnątrz *ngFor?
acdcjunior
Spróbuj zmienić nazwę zmiennej w środku na *ngForinną niż actionType, dobra?
acdcjunior
nie, nie mam, ale mam listę rozwijaną wyboru, którą iteruję, nie wiem, czy to jest źródło błędu, spójrz na moje zaktualizowane pytanie ...
Anna
61

Miałem ten sam problem. Brakowało mi znacznika importu modułu formularzy w pliku app.module.ts

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

@NgModule({
    imports: [BrowserModule,
        FormsModule
    ],
Chandan
źródło
2
dzięki za to, działało dobrze, ale powinno być app.module.ts, a nie app.module.component.ts
Salim
To nie jest praca dla mnie, chociaż ja już umieścić FormsModule importu w moim app.module
emirhosseini
9

Miałem ten sam problem, który został rozwiązany przez dodanie FormsModule do .spec.ts:

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

a następnie dodając import do beforeEach:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [ FormsModule ],
    declarations: [ YourComponent ]
  })
.compileComponents();
}));
Juha Ristolainen
źródło
5

Jeśli zamiast tego otrzymujesz to:

Błąd: błędy analizy szablonu:

Nie ma dyrektywy z opcją „exportAs” ustawioną na „ ngModel

Który został zgłoszony jako błąd w githubie , prawdopodobnie nie jest to błąd, ponieważ możesz:

  1. mają błąd składniowy (np. dodatkowy nawias:) [(ngModel)]]=, LUB
  2. być mieszanie reaktywnych form dyrektyw , takich jak formControlName, z ngModeldyrektywy . To „zostało wycofane w Angular v6 i zostanie usunięte w Angular v7” , ponieważ łączy obie strategie formularzy, co oznacza:
  • wygląda na ngModelto, że używana jest właściwa dyrektywa, ale w rzeczywistości jest to właściwość wejścia / wyjścia wymieniona ngModelw dyrektywie reactive form, która po prostu przybliża (niektóre) jej zachowanie. W szczególności umożliwia pobieranie / ustawianie wartości i przechwytywanie zdarzeń wartościowych. Jednak niektóre ngModelinne funkcje - takie jak opóźnianie aktualizacji za pomocą ngModelOpcji lub eksportowanie dyrektywy - po prostu nie działają (...)

  • ten wzorzec łączy strategie oparte na szablonie i strategie formularzy reaktywnych, których generalnie nie zalecamy, ponieważ nie wykorzystuje w pełni zalet obu strategii . (...)

  • Aby zaktualizować kod przed wersją 7, będziesz chciał zdecydować, czy trzymać się dyrektyw reaktywnych formularzy (i pobierać / ustawiać wartości za pomocą wzorców formularzy reaktywnych), czy też przełączyć się na dyrektywy oparte na szablonach .

Gdy masz takie dane wejściowe:

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

Wyświetli ostrzeżenie o strategiach formularzy mieszanych w konsoli przeglądarki:

Wygląda na to, że używasz ngModeltego samego pola formularza co formControlName.

Jeśli jednak dodasz ngModeljako wartość w zmiennej referencyjnej, przykład:

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

Następnie wyzwalany jest powyższy błąd i nie jest wyświetlane żadne ostrzeżenie o mieszaniu strategii.

CPHPython
źródło
4

W moim przypadku musiałem dodać FormsModulei ReactiveFormsModuledo tego shared.module.tsteż:

(podziękowania dla @Undrium za przykład kodu ):

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 { }
Sztylet
źródło
To rozwiązało mój problem. Dodanie go tylko do modułu app.module nie wystarczyło
emirhosseini
3

Miałem ten problem i zdałem sobie sprawę, że nie powiązałem mojego komponentu ze zmienną.

Zmieniony

<input #myComponent="ngModel" />

do

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

birwin
źródło
2

Prawidłowy sposób użycia formularzy w Angular2 to:

<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>

Stary sposób już nie działa

Ioses
źródło
1

Zrozumiano również, że ten problem pojawia się, gdy próbuje się połączyć podejście do formularza reaktywnego i formularza szablonu. Miałem #name="ngModel"i [formControl]="name"na tym samym elemencie. Usunięcie jednego z nich rozwiązało problem. Nie oznacza to również, że jeśli używasz #name=ngModel, powinieneś mieć również taką właściwość, jak ta [(ngModel)]="name", w przeciwnym razie nadal będziesz otrzymywać błędy. Dotyczy to również kątów 6, 7 i 8.

Samuel Mutemi
źródło
0

Sprawdź, czy masz ngModel and namew swoim wyborze oba atrybuty. Również Select jest składnikiem formularza, a nie całym formularzem, więc bardziej logiczna deklaracja lokalnego odniesienia będzie wyglądać następująco: -

<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>

Jeszcze jedną ważną rzeczą jest upewnienie się, że importujesz FormsModulew przypadku podejścia opartego na szablonie lub ReactiveFormsModulew przypadku podejścia reaktywnego. Lub możesz zaimportować oba, co również jest w porządku.

Rohan Shenoy
źródło
0

jeśli ngModulenie działa na wejściu, oznacza to, że spróbuj ... usunąć podwójne cudzysłowyngModule

lubić

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

zamiast powyżej

<input #form=ngModel [(ngModel)]......></input> try this
user13482587
źródło
-1

Miałem ten problem, ponieważ miałem literówkę w moim szablonie w pobliżu [(ngModel)]]. Dodatkowy wspornik. Przykład:

<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">
Raman Zhylich
źródło