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


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.


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

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();
}));

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.


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

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


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


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.


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.


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

-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">
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.