错误 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。
我刚好 运行 在我的申请中遇到了类似的问题。我实际上通过以下方式修复了它:
- 在我正在使用它的模块中导入
NgxMasonryModule
。在您的情况下,应该是声明 note.component
的模块
- 确保父模块(同样是您在其中声明
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
],
...
我正在尝试在我的 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。
我刚好 运行 在我的申请中遇到了类似的问题。我实际上通过以下方式修复了它:
- 在我正在使用它的模块中导入
NgxMasonryModule
。在您的情况下,应该是声明note.component
的模块 - 确保父模块(同样是您在其中声明
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
],
...