Angular 5迁移至Universal渲染遇NgbTypeaheadWindow组件报错求助
Hey there, let's work through this Angular Universal issue you're facing with NgbTypeaheadWindow! The problem usually stems from how third-party components like ng-bootstrap interact with server-side rendering—many of their internal components rely on browser APIs that aren't available during SSR, or we accidentally misconfigure their imports.
Here are the step-by-step fixes you should try:
1. Stop Manually Declaring NgbTypeaheadWindow
First, remove NgbTypeaheadWindow from both your AppModule and SharedModule. This component is an internal implementation detail of ng-bootstrap's typeahead feature, and it's already exported by NgbTypeaheadModule. Manually adding it to your modules will cause duplicate declaration errors, which is likely part of why your initial fix didn't work.
Instead, make sure your SharedModule (or whichever module uses the typeahead) properly imports the official ng-bootstrap module:
import { NgModule } from '@angular/core'; import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ imports: [ // Other modules... NgbTypeaheadModule ], exports: [ // Export it if other modules need to use typeahead NgbTypeaheadModule ] }) export class SharedModule { }
2. Add Browser Platform Checks for SSR Compatibility
The NgbTypeaheadWindow component relies on browser-specific DOM APIs that don't exist during server-side rendering. To avoid errors, wrap your typeahead component in a check that only renders it when running in the browser.
Here's how to implement this in your component:
import { Component, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Component({ selector: 'app-search-typeahead', template: ` <!-- Only render typeahead in the browser --> <ng-container *ngIf="isBrowser"> <input type="text" [(ngModel)]="selectedItem" [ngbTypeahead]="searchItems" placeholder="Search..." /> </ng-container> ` }) export class SearchTypeaheadComponent { isBrowser: boolean; selectedItem: string; constructor(@Inject(PLATFORM_ID) private platformId: Object) { // Detect if we're running in the browser this.isBrowser = isPlatformBrowser(this.platformId); } // Example typeahead search function searchItems = (text$: Observable<string>) => text$.pipe( map(term => term.length < 2 ? [] : ['Apple', 'Banana', 'Cherry'].filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1) ) ); }
3. (Last Resort) Use Schema to Ignore Unknown Components
If the above steps don't resolve the issue, you can add a schema to your modules to tell Angular to ignore unknown component errors. This is a fallback—use it sparingly, as it can hide other legitimate issues.
Add this to your AppModule and SharedModule:
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; @NgModule({ // Other imports/declarations... schemas: [NO_ERRORS_SCHEMA] }) export class AppModule { }
Once you've applied these fixes, rebuild your project with ng build --prod && ng run [your-project-name]:server:production (adjust the command to match your Angular CLI version) and then run node dist/server.js again. This should resolve the NgbTypeaheadWindow error.
内容的提问来源于stack exchange,提问作者John doe

