Angular 9.1.4 нг- bootstrap 6.1 Модальное содержимое не поддерживает ссылки на пользовательские компоненты - PullRequest
0 голосов
/ 03 мая 2020

Я разработал два Angular 9 компонента, которые используют класс NgbActiveModal и службу NgbModal ng- bootstrap 6.1 соответственно для отображения модальной формы при вызове пользовательского метода show ().

Здесь является компонентом содержимого:

<form ngForm #myForm name="loginToDealerForm" (ngSubmit)="onSubmit()" novalidate>
  <!-- #myForm="ngForm" -->
  <div class="modal-header">
    <h5 class="modal-title" id="loginToDealerModalTitle">Login to Dealer</h5>
    <button type="button" (click)="activeModal.close(false)" class="close" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <div class="col-12 col-md-2 text-left text-md-right">
      <label for="iqDealer">Reseller/Dealer:</label>
    </div>
    <!--<iq-dealer class="ui-front" #dealer
               name="dealer"
               (dealerChanged)="onDealerChange($event)"
               [caption]="'Reseller/Dealer'"
               [(ngModel)]="dealerID" [ngModelOptions]="{standalone: true}"
               [isRequired]="true"
               [showError]="myForm.submitted"
               [helpText]="'The organization that will invoice the end user'"></iq-dealer>-->
  </div>
  <div class="modal-footer justify-content-between">
    <!--<iq-popover-help *isIphone [help]="'To complete the selection, please press the &quot;return&quot; key on your iPhone keyboard (not &quot;done&quot;)'" [position]="'top'"></iq-popover-help>-->
    <button ngbAutofocus type="button" (click)="activeModal.close(false)" class="btn btn-warning">Cancel</button>
    <button [attr.disabled]="dealerID <= 0" type="submit" class="btn btn-primary">Select</button>
  </div>
</form>

Обратите внимание, что шаблон включает ссылки на два других пользовательских компонента <iq-dealer>...</iq-dealer> и <iq-popover-help>...</iq-popover-help>, которые закомментированы.

Вот код:

import { Component, OnInit, ViewChild, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { tap, flatMap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { Global } from '../global';
import { RESPONSIVE_DIRECTIVE, IsIphoneDirective, ResponsiveState } from 'ngx-responsive';
import { IqBaseComponent } from '../shared/iq-base.component';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { NgModel, FormsModule, NgForm } from '@angular/forms';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { IQService } from '../services/iq.service';
import { AppConfig } from '../services/app-config.service';
import { DealerComponent } from '../shared/dealer.component';
import { PopoverHelpComponent } from '../shared/popover-help.component';

/*------------ NgbActiveModal Modal Content Component   --------------*/
@Component({
  selector: 'iq-login-dealer-content',
  templateUrl: './login-dealer.component.html',
  styleUrls: []
})

export class LoginDealerContentComponent {

  dealerID: number = 0;

  constructor(public activeModal: NgbActiveModal,
    private iqService: IQService,
    private router: Router) { }

  ngOnInit() {
  }

  onDealerChange(value: number) {
    this.dealerID = value;
  }

  onSubmit() {
    if (this.dealerID > 0) {
      this.iqService.switchDealers(this.dealerID).pipe(
        tap(userProfile => {
          AppConfig.userProfile = userProfile;
          this.dealerID = 0;
        }),
        flatMap(userProfile => this.iqService.refreshToken(AppConfig.userProfile.userID, AppConfig.userProfile.organizationID)))
        .subscribe(result => {
          this.iqService.setToken(result);
          this.activeModal.close();
          this.router.navigate([Global.ROUTE_WELCOME]);
        },
          error => {
            this.iqService.postErrorMessage(error);
            this.dealerID = 0;
            this.activeModal.close();
          });
    }
  }

}

/*------------ NgbModal Modal Launcher Component   --------------*/
@Component({
  selector: 'iq-login-dealer',
  template: ''
})
export class LoginDealerComponent extends IqBaseComponent implements OnInit {

  constructor(private modalService: NgbModal,
    private responsiveState: ResponsiveState) {
    super(responsiveState);
  }

  ngOnInit() {

  }

  show() {
    const modalRef = this.modalService.open(LoginDealerContentComponent, { backdrop: true, keyboard: true });
  }
}

Таким образом, код работает очень хорошо и приводит к появлению следующего модального всплывающего окна при вызове метода show ():

Modal Popup

Проблема в том, что когда я назначаю ссылочную переменную шаблона #myForm="ngForm" в начальном теге элемента <form...> следующим образом:

<form ngForm #myForm="ngForm" name="loginToDealerForm" (ngSubmit)="onSubmit()" novalidate>

и удаляю комментарий к компоненту нестандартного дилера следующим образом: :

<iq-dealer class="ui-front" #dealer
               name="dealer"
               (dealerChanged)="onDealerChange($event)"
               [caption]="'Reseller/Dealer'"
               [(ngModel)]="dealerID" [ngModelOptions]="{standalone: true}"
               [isRequired]="true"
               [showError]="myForm.submitted"
               [helpText]="'The organization that will invoice the end user'"></iq-dealer>

Я получаю следующие ошибки транспилятора:

ERROR in src/app/login/login-dealer.component.html:13:5 - error NG8001: 'iq-dealer' is not a known element:
    1. If 'iq-dealer' is an Angular component, then verify that it is part of this module.
    2. If 'iq-dealer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

     13     <iq-dealer class="ui-front" #dealer
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     14                name="dealer"
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ...
     19                [showError]="myForm.submitted"
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     20                [helpText]="'The organization that will invoice the end user'"></iq-dealer>
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.
    src/app/login/login-dealer.component.html:16:16 - error NG8002: Can't bind to 'caption' since it isn't a known property of 'iq-dealer'.
    1. If 'iq-dealer' is an Angular component and it has 'caption' input, then verify that it is part of this module.
    2. If 'iq-dealer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
    3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

    16                [caption]="'Reseller/Dealer'"
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~m

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.
    src/app/login/login-dealer.component.html:17:16 - error NG8002: Can't bind to 'ngModel' since it isn't a known property of 'iq-dealer'.
    1. If 'iq-dealer' is an Angular component and it has 'ngModel' input, then verify that it is part of this module.
    2. If 'iq-dealer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
    3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

    17                [(ngModel)]="dealerID" [ngModelOptions]="{standalone: true}"
                      ~~~~~~~~~~~~~~~~~~~~~~

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.
    src/app/login/login-dealer.component.html:17:39 - error NG8002: Can't bind to 'ngModelOptions' since it isn't a known property of 'iq-dealer'.
    1. If 'iq-dealer' is an Angular component and it has 'ngModelOptions' input, then verify that it is part of this module.
    2. If 'iq-dealer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
    3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

    17                [(ngModel)]="dealerID" [ngModelOptions]="{standalone: true}"
                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.
    src/app/login/login-dealer.component.html:18:16 - error NG8002: Can't bind to 'isRequired' since it isn't a known property of 'iq-dealer'.
    1. If 'iq-dealer' is an Angular component and it has 'isRequired' input, then verify that it is part of this module.
    2. If 'iq-dealer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
    3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

    18                [isRequired]="true"
                      ~~~~~~~~~~~~~~~~~~~

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.
    src/app/login/login-dealer.component.html:19:16 - error NG8002: Can't bind to 'showError' since it isn't a known property of 'iq-dealer'.
    1. If 'iq-dealer' is an Angular component and it has 'showError' input, then verify that it is part of this module.
    2. If 'iq-dealer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
    3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

    19                [showError]="myForm.submitted"
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.
    src/app/login/login-dealer.component.html:20:16 - error NG8002: Can't bind to 'helpText' since it isn't a known property of 'iq-dealer'.
    1. If 'iq-dealer' is an Angular component and it has 'helpText' input, then verify that it is part of this module.
    2. If 'iq-dealer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
    3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

    20                [helpText]="'The organization that will invoice the end user'"></iq-dealer>
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.
    src/app/login/login-dealer.component.html:1:23 - error NG8003: No directive found with exportAs 'ngForm'.

    1 <form ngForm #myForm="ngForm" name="loginToDealerForm" (ngSubmit)="onSubmit()" novalidate>
                            ~~~~~~

      src/app/login/login-dealer.component.ts:19:16
        19   templateUrl: './login-dealer.component.html',
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Error occurs in the template of component LoginDealerContentComponent.

Поиск предложений по устранению этих ошибок после попыток найти множество советов, найденных в других местах, и добавления множества рекомендуемых импортов.

...