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

时间:2020-07-08 13:33:55

标签: angular angular-reactive-forms

我已经在shared.module.ts中导入了ReactiveFormsModule。它在许多形式之间共享。我正在建立一个新表单,但是由于某种原因,我在此行上收到此错误

<form [formGroup]="additionalInterestsForm" (ngSubmit)="submit()" class="additionalInterests">

我不确定我缺少什么。我的component.ts文件成功导入了FormGroup并使用了它。我相信ReactiveFormsModule不会像以前对类似问题的许多回答所建议的那样成为问题,因为我已经创建了另外两种形式并且它们都可以工作,并且我从未将ReactiveFormsModule导入到任何其他模块中,因为它已经在共享模块中导入

我不确定要显示更清晰的图片需要显示什么代码。

这是shared.module.ts。

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatMenuModule } from '@angular/material/menu';
import { MatSelectModule } from '@angular/material/select';
import { MatTabsModule } from '@angular/material/tabs';
import { MatInputModule } from '@angular/material/input';
import { MatProgressSpinnerModule } from '@angular/material/progress-
spinner';
import { MatChipsModule } from '@angular/material/chips';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatCardModule } from '@angular/material/card';
import { MatListModule } from '@angular/material/list';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatDividerModule } from '@angular/material/divider';
import { MatSliderModule } from '@angular/material/slider';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-
fontawesome';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatStepperModule } from '@angular/material/stepper';
import { MatRadioModule } from '@angular/material/radio';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatDialogModule } from '@angular/material/dialog';
import { MatTreeModule } from '@angular/material/tree';
import { MatTableModule } from '@angular/material/table';
import { MatBadgeModule } from '@angular/material/badge';
import {
    fas
} from '@fortawesome/free-solid-svg-icons';
import {
    fab
} from '@fortawesome/free-brands-svg-icons';
import {
    far
} from '@fortawesome/free-regular-svg-icons'



import { BigInputComponent } from './big-input/big-input.component';
import { BigInputActionComponent } from './big-input/big-input-
action.component';

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        ReactiveFormsModule,
        MatFormFieldModule,
        TranslateModule,
        FlexLayoutModule,
        MatButtonModule,
        MatToolbarModule,
        MatSelectModule,
        MatTabsModule,
        MatInputModule,
        MatProgressSpinnerModule,
        MatChipsModule,
        MatCardModule,
        MatSidenavModule,
        MatCheckboxModule,
        MatListModule,
        MatMenuModule,
        MatTooltipModule,
        MatSnackBarModule,
        MatSlideToggleModule,
        MatDividerModule,
        MatGridListModule,
        FontAwesomeModule,
        MatStepperModule,
        MatIconModule,
        MatRadioModule,
        MatAutocompleteModule,
        MatExpansionModule,
        MatDialogModule,
        MatTreeModule,
        MatTableModule,
        MatBadgeModule
    ], 
    declarations: [BigInputComponent, BigInputActionComponent],
    exports: [
        CommonModule,
        FormsModule,
        ReactiveFormsModule,
        MatGridListModule,
        TranslateModule,
        MatFormFieldModule,
        MatButtonModule,
        MatMenuModule,
        MatTabsModule,
        MatChipsModule,
        MatInputModule,
        MatProgressSpinnerModule,
        MatCheckboxModule,
        MatCardModule,
        MatSidenavModule,
        MatListModule,
        MatSelectModule,
        MatToolbarModule,
        MatTooltipModule,
        MatSnackBarModule,
        MatSlideToggleModule,
        MatDividerModule,
        MatSliderModule,
        MatDatepickerModule,
        MatNativeDateModule,
        MatProgressBarModule,
        FontAwesomeModule,
        FlexLayoutModule,
        BigInputComponent,
        BigInputActionComponent,
        MatStepperModule,
        MatIconModule,
        MatRadioModule,
        MatAutocompleteModule,
        MatExpansionModule,
        MatDialogModule,
        MatTreeModule,
        MatTableModule,
        MatBadgeModule

    ]
})
export class SharedModule {

    constructor(private library: FaIconLibrary) {
         library.addIconPacks(fas, far, fab);
         //library.addIcons(faBars);
    }
}

这是app.module.ts。

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-
browser/animations';
import { NgModule } from '@angular/core';
import { SharedModule } from '@app/shared';
import { SettingsModule } from './settings';
import { StaticModule } from './static';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AuthService } from './core/auth/auth.service';
import { LoggingInterceptor } from './core/http-interceptors/http-
logging.interceptor';
import { SignalRModule } from 'ng2-signalr';
import { createConfig } from './core/signalr/signal.model';
import { ConnectionResolver } from './core/signalr/signalr.service';
import { HttpErrorInterceptor } from './core/http-interceptors/http-
error.interceptor';
import { CoreModule } from './core/core.module';
import { DynamicModuleLoader } from './dynamic-module/dynamic-module-
loader.module';
import { FormLoginComponent, LoginDialog } from './form-login/form-
login.component';
import { PolicyDialog, FormPolicyComponent } from './form-policy-search/form-
policy-search.component';
import { MenuListItemComponent, NavService } from './menu-tree/menu-list-
item.component';
import { FormInsuredDetailComponent } from './form-insured-detail/form-
insured-detail.component';
import { FormAddressComponent } from './form-address/form-address.component';
import { FormMortgageeComponent } from './form-mortgagee-detail/form-
mortgagee-detail.component';
import { FormCoverageComponent } from './form-basic-coverage/form-
coverage.component';
import { FormRatingComponent } from './form-rating/form-rating.component';
import { FormUnderwritingComponent } from './form-underwriting/form-
underwriting.component';
import { FormAdditionalInfoComponent } from './form-additional-info/form-
additional-info.component';
import { FormCancellationComponent } from './form-cancellation/form-
cancellation.component';
import { FormReinstatementComponent } from './form-reinstatement/form-
reinstatement.component';
import { QueueCartComponent } from './queue-cart/queue-cart.component';
import { PolicyConfirmationDialog } from './form-policy-search/policy-
confirmation-dialog/policy-confirmation-dialog.component';
import { SubmitedMenuComponent } from './submited-menu/submited-
menu.component';
import { SubmitedDetailsDialog } from './submited-menu/submited-details-
dialog/submited-details-dialog.component';
import { FormMicComponent } from './form-mic/form-mic.component';
import { FormCommentComponent } from './form-comment/form-comment.component';
import { QueueCartConfirmationDialog } from './queue-cart/queue-cart-
confirmation-dialog/queue-cart-confirmation-dialog.component';
import { QuestionService } from './dynamic-
module/questions/service/question.service';
import { QuestionControlService } from './dynamic-
module/questions/service/question-control.service';
import { FormAdditionalInsured } from './form-additional-insured/form-
additional-insured.component';
@NgModule({
    imports: [



         // angular
        BrowserAnimationsModule,
        BrowserModule,

         // core & shared
        CoreModule,
        SharedModule,
         // features
        StaticModule,
        SettingsModule,

         // app
        AppRoutingModule,
        SignalRModule.forRoot(createConfig),
        DynamicModuleLoader,
    ],
    declarations: [
         AppComponent,
         FormLoginComponent,
         FormPolicyComponent,
         LoginDialog,
         PolicyDialog,
         PolicyConfirmationDialog,
         MenuListItemComponent,
         FormInsuredDetailComponent,
         FormAddressComponent,
         FormMortgageeComponent,
         FormCoverageComponent,
         FormRatingComponent,
         FormUnderwritingComponent,
         FormAdditionalInfoComponent,
         FormAdditionalInsured,
         FormCancellationComponent,
         FormReinstatementComponent,
         QueueCartComponent,
         SubmitedMenuComponent,
         SubmitedDetailsDialog,
         FormMicComponent,
         FormCommentComponent,
         QueueCartConfirmationDialog
    ],
    providers: [AuthService, HttpErrorInterceptor, LoggingInterceptor, 
    ConnectionResolver, NavService, QuestionService, QuestionControlService],
    //QuestionService,QuestionControlService remove after demo
    bootstrap: [AppComponent],
    entryComponents: [LoginDialog, PolicyDialog, PolicyConfirmationDialog, 
    SubmitedDetailsDialog, QueueCartConfirmationDialog]
})
export class AppModule {

     //constructor(private _signalR: ConnectionResolver) {

    //}
}

组件

import { Component, ChangeDetectionStrategy, OnInit, Output, Input, 
EventEmitter } from '@angular/core';
import { DynamicComponentBase } from '../../dynamic-component-base';
import { ROUTE_ANIMATIONS_ELEMENTS, AppState } from '../../../../core';
import { FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';
import { AdditionalInterestsFormModel, AdditionalInterestsFormElements } from 
'../../../../core/store/forms/additional-interests/additional-interests-
form.model';
import { selectLoadingAdditionalInterest, selectPolicyIsReadOnly, 
selectIsAdditionalInterestsInCart, selectIsAdditionalInterestsSubmitted } 
from '../../../../core/store/policy/policy.selectors';
import { Store } from '@ngrx/store';
import { QueueCartItem, AdditionalInterests } from 
'../../../../core/store/policy/policy.models';
import { QuestionService } from 
'../../../questions/service/question.service';
import { QuestionControlService } from '../../../questions/service/question-
control.service';

@Component({
  selector: 'app-additional-interests-form-component',
  templateUrl: './additional-interests-form.component.html',
  styleUrls: ["./additional-interests-form.component.scss"],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class AdditionalInterestsFormComponent implements OnInit, 
DynamicComponentBase {
  routeAnimationsElements = ROUTE_ANIMATIONS_ELEMENTS;
  @Output() dynamicComponentPayLoad = new EventEmitter<FormGroup>();
  @Output() stepperGoBack = new EventEmitter<string>();
  @Output() stepperGoForward = new EventEmitter<string>();
  @Input() showBackButton: boolean;
  @Input() extraData: any;
  tab1Name: string = "Policy View";
  tab2Name: string = "Save View";
  tab3Name: string = "Submit View";
  questionKeys: string[] = [];
  additionalInterestsForm: FormGroup;
  formValueChanges$: Observable<AdditionalInterestsFormModel>;
  activeTab: number = 0;
  questions: any[];
  isReadOnly: boolean;
  loadingData$: Observable<boolean> = 
  this.store.select(selectLoadingAdditionalInterest);
  isInCart$: Observable<boolean> = 
  this.store.select(selectIsAdditionalInterestsInCart);
  isSubmitted$: Observable<boolean> = 
  this.store.select(selectIsAdditionalInterestsSubmitted);

  private defaultAdditionalInterestsDetailModel: 
  AdditionalInterestsFormModel;
  private formNames: string[];
  private cart: QueueCartItem[];
  private submittedChanges: QueueCartItem[];
  private additionalInterests: AdditionalInterests;

  constructor(private store: Store<AppState>,
    private questionService: QuestionService,
    private questionControlService: QuestionControlService) {

    this.store.select(selectPolicyIsReadOnly).subscribe(isReadOnly => {
      this.isReadOnly = isReadOnly;
    })

  }

  ngOnInit(): void {
     let formControl = new AdditionalInterestsFormElements();
     this.formNames = Object.getOwnPropertyNames(formControl);
     let tempQuestions: any[] = 
 this.questionService.getQuestionsByKeys(this.formNames);
     this.questions = tempQuestions;
     this.additionalInterestsForm = 
     this.questionControlService.toFormGroup(tempQuestions, this.isReadOnly);
  }

   tabChanged($event) {
    //this.buidTabView($event.tab.textLabel);
   }

  goBack() {
    this.stepperGoBack.emit('')
  }

  goForward() {
    this.stepperGoForward.emit('')
  }

  reset() {

  }

  submit() {
    if (this.additionalInterestsForm.valid) {
      this.additionalInterestsForm.markAsPristine();
    }
  }
}

视图

<mat-progress-bar *ngIf="(loadingData$ | async)" mode="indeterminate"></mat-
progress-bar>
<form [formGroup]="additionalInterestsForm" (ngSubmit)="submit()" 
class="additionalInterests">
  <div class="justify-content-center">
    <mat-card class="" [ngClass]="routeAnimationsElements">
      <div fxLayout="column">
        <mat-card-title style="margin-left:50px; margin-bottom:20px;">
           Additional Interests
        </mat-card-title>
        <mat-card-content>
           <mat-tab-group [(selectedIndex)]="activeTab" 
  (selectedTabChange)="tabChanged($event)" color="warn">
              <mat-tab label="{{tab1Name}}">
              <ng-template matTabContent>
                <div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutGap="20px" class="fnol-min-widht50">
                  <div *ngFor="let question of questions" style="  width: 40%;">
                     <app-question [question]="question" [formGroup]="additionalInterestsForm"></app-question>
                  </div>
                 </div>
               </ng-template>
            </mat-tab>
            <mat-tab label="{{tab2Name}}" [disabled]="!(isInCart$ | async)">
               <ng-template matTabContent>
                <div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutGap="20px" class="fnol-min-widht50">
                  <div *ngFor="let question of questions" style="  width: 40%;">
                    <app-question [question]="question" [formGroup]="additionalInterestsForm"></app-question>
                  </div>
                </div>
              </ng-template>
            </mat-tab>
            <mat-tab label={{tab3Name}} [disabled]="!(isSubmitted$ | async)">
              <ng-template matTabContent>
                <div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutGap="20px" class="fnol-min-widht50">
                  <div *ngFor="let question of questions" style="  width: 40%;">
                    <app-question [question]="question" [formGroup]="additionalInterestsForm"></app-question>
                  </div>
                </div>
              </ng-template>
            </mat-tab>
          </mat-tab-group>

        </mat-card-content>
      </div>
      <mat-card-actions *ngIf="!isReadOnly">
        <div class="row buttons d-flex" fxLayoutAlign="end">
          <div class="row buttons justify-content-between pad form-container-action-buttons">
            <button mat-raised-button type="button" (click)="reset()" [ngClass]="routeAnimationsElements">Reset</button>
            <button mat-raised-button color="primary" type="submit" [ngClass]="routeAnimationsElements" [disabled]="!additionalInsuredForm.valid||additionalInsuredForm.pristine" (click)="goForward()">SAVE TO QUEUE</button>
          </div>

        </div>
      </mat-card-actions>
    </mat-card>
  </div>
</form>

组件模块

import { NgModule } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { SharedModule } from '../../../shared';
import { ArchwizardModule } from 'angular-archwizard';
import { DynamicFormQuestionModule } from '../../questions/dynamic-form-
question.module';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { AdditionalInterestsFormComponent } from "./additional-interests-
components/additional-interests-form.component";
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { environment } from '../../../../environments/environment';

NgModule({
  declarations: [
    AdditionalInterestsFormComponent
  ],
  entryComponents: [AdditionalInterestsFormComponent],
  imports: [
    SharedModule,
    ArchwizardModule,
    //DynamicComponentLoaderModule.forChild(AddressFormComponent),
    DynamicFormQuestionModule,
    TranslateModule.forChild({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      },
      isolate: true
    })
  ]
})

export class AdditionalInterestsFormModule {
  static entry = AdditionalInterestsFormComponent;
}
export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(
    http,
    `${environment.i18nPrefix}/assets/i18n/examples/`,
    '.json'
  );
}

2 个答案:

答案 0 :(得分:1)

您尚未在导入数组中导入ReactiveFormsModule。您刚刚将其添加到了导出数组中。

答案 1 :(得分:0)

我的组件模块缺少“ @”

就是这样

NgModule

代替

@NgModule