错误 NG8001:'ngx-masonry' 不是已知元素

error NG8001: 'ngx-masonry' is not a known element

我正在尝试在我的 JHipster 应用程序(angluar 应用程序)中导入模块 ngx-masonry

我运行

npm install ngx-masonry masonry-layout --save

然后导入里面的模块app.module.ts

import { NgModule, LOCALE_ID } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import locale from '@angular/common/locales/en';
import { BrowserModule, Title } from '@angular/platform-browser';
import { ServiceWorkerModule } from '@angular/service-worker';
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { TranslateModule, TranslateService, TranslateLoader, MissingTranslationHandler } from '@ngx-translate/core';
import { NgxWebstorageModule, SessionStorageService } from 'ngx-webstorage';
import * as dayjs from 'dayjs';
import { NgbDateAdapter, NgbDatepickerConfig } from '@ng-bootstrap/ng-bootstrap';

import { ApplicationConfigService } from 'app/core/config/application-config.service';
import './config/dayjs';
import { SharedModule } from 'app/shared/shared.module';
import { AppRoutingModule } from './app-routing.module';
import { HomeModule } from './home/home.module';
import { EntityRoutingModule } from './entities/entity-routing.module';
// jhipster-needle-angular-add-module-import JHipster will add new module here
import { NgbDateDayjsAdapter } from './config/datepicker-adapter';
import { fontAwesomeIcons } from './config/font-awesome-icons';
import { httpInterceptorProviders } from 'app/core/interceptor/index';
import { translatePartialLoader, missingTranslationHandler } from './config/translation.config';
import { MainComponent } from './layouts/main/main.component';
import { NavbarComponent } from './layouts/navbar/navbar.component';
import { FooterComponent } from './layouts/footer/footer.component';
import { PageRibbonComponent } from './layouts/profiles/page-ribbon.component';
import { ActiveMenuDirective } from './layouts/navbar/active-menu.directive';
import { ErrorComponent } from './layouts/error/error.component';
import 'jquery/dist/jquery.js';
import '@angular/animations';
import { NgxMasonryModule } from 'ngx-masonry';

@NgModule({
  imports: [
    NgxMasonryModule,
    BrowserModule,
    SharedModule,
    HomeModule,
    // jhipster-needle-angular-add-module JHipster will add new module here
    EntityRoutingModule,
    AppRoutingModule,
    // Set this to true to enable service worker (PWA)
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: false }),
    HttpClientModule,
    NgxWebstorageModule.forRoot({ prefix: 'jhi', separator: '-', caseSensitive: true }),
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: translatePartialLoader,
        deps: [HttpClient],
      },
      missingTranslationHandler: {
        provide: MissingTranslationHandler,
        useFactory: missingTranslationHandler,
      },
    }),
  ],
  providers: [
    Title,
    { provide: LOCALE_ID, useValue: 'en' },
    { provide: NgbDateAdapter, useClass: NgbDateDayjsAdapter },
    httpInterceptorProviders,
  ],
  declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
  bootstrap: [MainComponent],
})
export class AppModule {
  constructor(
    applicationConfigService: ApplicationConfigService,
    iconLibrary: FaIconLibrary,
    dpConfig: NgbDatepickerConfig,
    translateService: TranslateService,
    sessionStorageService: SessionStorageService
  ) {
    applicationConfigService.setEndpointPrefix(SERVER_API_URL);
    registerLocaleData(locale);
    iconLibrary.addIcons(...fontAwesomeIcons);
    dpConfig.minDate = { year: dayjs().subtract(100, 'year').year(), month: 1, day: 1 };
    translateService.setDefaultLang('en');
    // if user have changed language and navigates away from the application and back to the application then use previously choosed language
    const langKey = sessionStorageService.retrieve('locale') ?? 'en';
    translateService.use(langKey);
  }
}

然后我使用了note.component.html文件里面的组件:

...Other html code...
  <ngx-masonry>
  <div class="grid" ngxMasonryItem >
    <div class="grid-item card-selectable" *ngFor="let note of notes; trackBy: trackId">
      <div [routerLink]="['/note', note.id, 'edit']">
        <h5>{{note.title}}</h5>
      </div>
      </div>
    </div>
  </div>
  </ngx-masonry>
...Other html code...

我也试过直接在 note.component.ts:

中导入模块
import { Component, OnInit } from '@angular/core';
import { HttpHeaders, HttpResponse } from '@angular/common/http';
import { ActivatedRoute } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

import { INote } from '../note.model';

import { ASC, DESC, ITEMS_PER_PAGE } from 'app/config/pagination.constants';
import { NoteService } from '../service/note.service';
import { NoteDeleteDialogComponent } from '../delete/note-delete-dialog.component';
import { ParseLinks } from 'app/core/util/parse-links.service';
import { NgxMasonryModule } from 'ngx-masonry';

@Component({
  selector: 'jhi-note',
  templateUrl: './note.component.html',
})
export class NoteComponent implements OnInit {
  notes: INote[];
  isLoading = false;
  itemsPerPage: number;
  links: { [key: string]: number };
  page: number;
  predicate: string;
  ascending: boolean;
  currentSearch: string;

  constructor(
    protected noteService: NoteService,
    protected modalService: NgbModal,
    protected parseLinks: ParseLinks,
    protected activatedRoute: ActivatedRoute
  ) {
    this.notes = [];
    this.itemsPerPage = ITEMS_PER_PAGE;
    this.page = 0;
    this.links = {
      last: 0,
    };
    this.predicate = 'id';
    this.ascending = true;
    this.currentSearch = this.activatedRoute.snapshot.queryParams['search'] ?? '';
  }

  loadAll(): void {
    this.isLoading = true;
    if (this.currentSearch) {
      this.noteService
        .search({
          query: this.currentSearch,
          page: this.page,
          size: this.itemsPerPage,
          sort: this.sort(),
        })
        .subscribe(
          (res: HttpResponse<INote[]>) => {
            this.isLoading = false;
            this.paginateNotes(res.body, res.headers);
          },
          () => {
            this.isLoading = false;
          }
        );
      return;
    }

    this.noteService
      .query({
        page: this.page,
        size: this.itemsPerPage,
        sort: this.sort(),
      })
      .subscribe(
        (res: HttpResponse<INote[]>) => {
          this.isLoading = false;
          this.paginateNotes(res.body, res.headers);
        },
        () => {
          this.isLoading = false;
        }
      );
  }

  reset(): void {
    this.page = 0;
    this.notes = [];
    this.loadAll();
  }

  loadPage(page: number): void {
    this.page = page;
    this.loadAll();
  }

  search(query: string): void {
    this.notes = [];
    this.links = {
      last: 0,
    };
    this.page = 0;
    if (query && ['hashcode', 'title', 'textContent', 'color'].includes(this.predicate)) {
      this.predicate = 'id';
      this.ascending = true;
    }
    this.currentSearch = query;
    this.loadAll();
  }

  ngOnInit(): void {
    this.loadAll();
  }

  trackId(index: number, item: INote): number {
    return item.id!;
  }

  delete(note: INote): void {
    const modalRef = this.modalService.open(NoteDeleteDialogComponent, { size: 'lg', backdrop: 'static' });
    modalRef.componentInstance.note = note;
    // unsubscribe not needed because closed completes on modal close
    modalRef.closed.subscribe(reason => {
      if (reason === 'deleted') {
        this.reset();
      }
    });
  }

  createTestNotes(): void {
    this.noteService.createTestNotes().subscribe(() => {this.reset()});
  }

  deleteAllNotes(): void {
    this.noteService.deleteAllNotes().subscribe(() => {this.reset()});
  }

  protected sort(): string[] {
    const result = [this.predicate + ',' + (this.ascending ? ASC : DESC)];
    if (this.predicate !== 'id') {
      result.push('id');
    }
    return result;
  }

  protected paginateNotes(data: INote[] | null, headers: HttpHeaders): void {
    this.links = this.parseLinks.parse(headers.get('link') ?? '');
    if (data) {
      for (const d of data) {
        this.notes.push(d);
      }
    }
  }
}

但不断收到此错误:

2021-10-15T09:40:50.710+0200 [ERROR] [system.err] Error: src/main/webapp/app/entities/note/list/note.component.html:73:7 - error NG8001: 'ngx-masonry' is not a known element:
2021-10-15T09:40:50.710+0200 [ERROR] [system.err] 1. If 'ngx-masonry' is an Angular component, then verify that it is part of this module.
2021-10-15T09:40:50.710+0200 [ERROR] [system.err] 2. If 'ngx-masonry' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
2021-10-15T09:40:50.711+0200 [ERROR] [system.err] 
2021-10-15T09:40:50.711+0200 [ERROR] [system.err] 73       <ngx-masonry>
2021-10-15T09:40:50.711+0200 [ERROR] [system.err]          ~~~~~~~~~~~~~
2021-10-15T09:40:50.711+0200 [ERROR] [system.err] 
2021-10-15T09:40:50.711+0200 [ERROR] [system.err]   src/main/webapp/app/entities/note/list/note.component.ts:17:16
2021-10-15T09:40:50.711+0200 [ERROR] [system.err]     17   templateUrl: './note.component.html',
2021-10-15T09:40:50.712+0200 [ERROR] [system.err]                       ~~~~~~~~~~~~~~~~~~~~~~~
2021-10-15T09:40:50.712+0200 [ERROR] [system.err]     Error occurs in the template of component NoteComponent.

我的 package.json 包括:

"jquery": "^3.6.0",
"masonry-layout": "^4.2.2",
"ngx-infinite-scroll": "10.0.1",
"ngx-masonry": "^12.0.0",
"@types/jquery": "3.5.7",
"@types/masonry-layout": "4.2.4",

已经尝试停止服务器、npm、重新启动 IDE。

我刚好 运行 在我的申请中遇到了类似的问题。我实际上通过以下方式修复了它:

  1. 在我正在使用它的模块中导入 NgxMasonryModule。在您的情况下,应该是声明 note.component 的模块
  2. 确保父模块(同样是您在其中声明 note.component 的模块)作为上面每个父模块中的模块都很重要。在我的例子中,我没有导入我正在使用包的模块作为模块,而是作为组件。

导致:

note.module(声明note.component的模块)

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; 
import { NoteComponent } from './content-grid.component';
import { NgxMasonryModule } from 'ngx-masonry';

@NgModule({
  declarations: [
    NoteComponent
  ],
  imports: [
    CommonModule,
    NgxMasonryModule
  ]
})

export class NoteModule { 
}

如果您在另一个模块中使用 NoteModule,请确保 NoteModule 和其他模块都作为模块导入,而不是作为组件导入。

app.module

...
@NgModule({
  declarations: [
    ...
  ],
  imports: [
    NoteModule
  ],
...