You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Angular 13升级到16后管道及属性绑定报错求助

Angular 13升级到16后自定义管道及ngClass绑定问题排查

问题描述

将Angular项目从13版本逐步升级至16版本后,启动项目时出现两个核心错误:

  • 找不到名为translate的自定义管道
  • 无法绑定到ngClass(提示其不是button的已知属性)

已尝试删除并重新安装node_modules,问题未解决。

具体错误示例

找不到名为'translate'的管道。

模板中管道使用代码:

{{'_AVERAGE_HANDLING_TIME_' | translate}}

现有模块配置

已将translate管道导入PipesModule,PipesModule导入至SharedModule,SharedModule又导入至AppModule,相关模块代码如下:

pipes.module.ts

import { NgModule } from '@angular/core';
import { TranslatePipe } from './translate.pipe';
import { SafePipe } from './safe.pipe';
import { DashboardSearchPipe, GenderTextPipe, SuggestionSearchPipe, TaskTemplateSearchPipe, TemplateTypePipe, WallboardSearchPipe } from './custome.pipe';

@NgModule({
    exports: [
        TranslatePipe,
        SafePipe,
        TemplateTypePipe,
        SuggestionSearchPipe,
        TaskTemplateSearchPipe,
        DashboardSearchPipe,
        GenderTextPipe,
        WallboardSearchPipe
    ],
    declarations: [
        TranslatePipe,
        SafePipe,
        TemplateTypePipe,
        SuggestionSearchPipe,
        TaskTemplateSearchPipe,
        DashboardSearchPipe,
        GenderTextPipe,
        WallboardSearchPipe
    ],
    providers: [
        TranslatePipe,
        SafePipe,
        TemplateTypePipe,
        SuggestionSearchPipe,
        TaskTemplateSearchPipe,
        DashboardSearchPipe,
        GenderTextPipe,
        WallboardSearchPipe
    ]
  })
  export class PipesModule { }

shared.module.ts

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { PipesModule } from '../pipes/pipes.module';
import { AppRoutingModule } from '../app.routing.module';
import { EditorModule } from '@tinymce/tinymce-angular';
import { TagInputModule } from 'ngx-chips';
import { AngularMaterialCommonModule } from '../angular-material-common.module';
import { DirectivesModule } from '../directives/directive.module';

@NgModule({
    imports: [
        CommonModule,
        AppRoutingModule,
        EditorModule,
        TagInputModule,
        FormsModule,
        ReactiveFormsModule,
        AngularMaterialCommonModule,
        PipesModule,
        DirectivesModule
    ],
    declarations: [],
    exports: [
        CommonModule,
        AppRoutingModule,
        EditorModule,
        TagInputModule,
        FormsModule,
        ReactiveFormsModule,
        AngularMaterialCommonModule,
        PipesModule,
        DirectivesModule
    ],
})
export class SharedModule { }

app.module.ts

import { APP_INITIALIZER, NgModule } from '@angular/core';
import { TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular';
import { defineLocale } from 'ngx-bootstrap/chronos';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { nlLocale } from 'ngx-bootstrap/locale';
import { ModalModule } from 'ngx-bootstrap/modal';
import { AppComponent } from './app.component';
import { AuditLogComponent } from './auditlog/auditlog.component';
import { CaseSearchResultComponent } from './case/casesearchresult.component';
import { AboutUsComponent } from './common/aboutus.component';
import { AppLoaderComponent } from './common/apploader.component';
import { AuthGuard } from './common/auth.guard';
import { HeaderComponent } from './common/header.component';
import { LinkUnlinkEntityComponent } from './common/linkunlinkentity.component';
import { LoginComponent } from './common/login.component';
import { MessageBoxComponent } from './common/messagebox.component';
import { ProgressBarComponent } from './common/progress-bar.component';
import { SearchPopupComponent } from './common/searchpopup.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { DashboardConfigComponent } from './dashboardconfig/dashboardconfig.component';
import { DashboardWebpartComponent } from './dashboardconfig/dashboardwebpart.component';
import { DocumentSearchResultComponent } from './document/documentsearchresult.component';
import { EmployeeSearchResultComponent } from './employee/employeesearchresult.component';
import { FileSearchResultComponent } from './fileentity/fileentitysearchresult.component';
import { LinkSearchResultComponent } from './link/linksearchresult.component';
import { NewsSearchResultComponent } from './news/newssearchresult.component';
import { NoteEntitySearchResultComponent } from './noteentity/noteentitysearchresult.component';
import { OrganizationSearchResultComponent } from './organization/organizationsearchresult.component';
import { PersonSearchResultComponent } from './person/personsearchresult.component';
import { ProductSearchResultComponent } from './product/productsearchresult.component';
import { QuestionAnswerSearchResultComponent } from './questionanswer/questionanswersearchresult.component';
import { ReportComponent } from './report/report.component';
import { LocalizeService } from './services/localize.service';
import { SharedModule } from './shared/shared.module';
import { SuggestionPanelComponent } from './suggestionpanel/suggestionpanel.component';
import { EmailTemplateComponent } from './template/emailtemplate.component';
import { TaskTemplateComponent } from './template/tasktemplate.component';
import { TemplateComponent } from './template/template.component';
import { ThemeSearchResultComponent } from './theme/themesearchresult.component';
import { TicketSearchResultComponent } from './ticket/ticketsearchresult.component';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { WallboardModule } from './wallboard/wallboard.module';
import { CommonModule } from '@angular/common';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    HeaderComponent,
    DashboardComponent,
    AppLoaderComponent,
    ReportComponent,
    EmailTemplateComponent,
    AuditLogComponent,
    SuggestionPanelComponent,
    DashboardConfigComponent, 
    DashboardWebpartComponent,
    AboutUsComponent,
    LinkUnlinkEntityComponent,
    SearchPopupComponent, 
    FileSearchResultComponent, 
    EmployeeSearchResultComponent, 
    ThemeSearchResultComponent, 
    NoteEntitySearchResultComponent, 
    ProductSearchResultComponent, 
    QuestionAnswerSearchResultComponent, 
    LinkSearchResultComponent, 
    NewsSearchResultComponent, 
    PersonSearchResultComponent, 
    OrganizationSearchResultComponent, 
    DocumentSearchResultComponent, 
    CaseSearchResultComponent, 
    TicketSearchResultComponent,
    TemplateComponent, 
    TaskTemplateComponent,
    MessageBoxComponent, 
    ProgressBarComponent
  ],
  imports: [
    CommonModule,
    SharedModule,
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    WallboardModule,
    BsDropdownModule.forRoot(),
    ModalModule.forRoot(),
    BsDatepickerModule.forRoot(),
    
  ],
  providers: [
    AuthGuard,
    LocalizeService,
    {
      provide: APP_INITIALIZER,
      useFactory: setupTranslateFactory,
      deps: [LocalizeService],
      multi: true
    },
    { provide: TINYMCE_SCRIPT_SRC, useValue: 'tinymce/tinymce.min.js' }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

export function setupTranslateFactory(
  localizeService: LocalizeService): Function {
  return () => {
    localizeService.setLanguage().then((language) => {
      localizeService.useLanguage(language == 'nl-NL' ? 'NL' : 'EN').then(() => {
        console.log("language set as: " + language);
      });
      if (language == 'nl-NL')
        defineLocale('nl', nlLocale);
    });
  };
}

package.json

{
  "name": "decos-kcs-web",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^16.2.12",
    "@angular/cdk": "^16.2.14",
    "@angular/common": "^16.2.12",
    "@angular/compiler": "^16.2.12",
    "@angular/core": "^16.2.12",
    "@angular/forms": "^16.2.12",
    "@angular/localize": "^16.2.12",
    "@angular/material": "^16.2.14",
    "@angular/platform-browser": "^16.2.12",
    "@angular/platform-browser-dynamic": "^16.2.12",
    "@angular/router": "^16.2.12",
    "@tinymce/tinymce-angular": "^6.0.1",
    "angular-moment": "^1.3.0",
    "chart.js": "^4.4.3",
    "jlinq": "^1.0.0",
    "lz-string": "^1.5.0",
    "moment": "^2.29.4",
    "ngx-bootstrap": "^5.1.2",
    "ngx-chips": "^3.0.0",
    "rxjs": "^7.8.1",
    "spin.js": "^4.0.0",
    "tinymce": "^7.3.0",
    "tslib": "^2.0.0",
    "x2js": "^3.3.0",
    "zone.js": "^0.14.10"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^16.2.14",
    "@angular/cli": "^16.2.14",
    "@angular/compiler-cli": "^16.2.12",
    "@angular/language-service": "^16.2.12",
    "@types/node": "~20.8.2",
    "typescript": "4.9.5"
  }
}

问题根源及解决方案

1. 自定义管道注册冗余导致冲突

Angular 16中,自定义管道不需要再添加到providers数组中,仅需在declarations声明并通过exports导出即可。当前PipesModule的providers数组包含所有管道,这在新版本中属于冗余配置,可能引发管道识别异常。

修改方案:移除PipesModule中的providers数组,修改后的代码如下:

import { NgModule } from '@angular/core';
import { TranslatePipe } from './translate.pipe';
import { SafePipe } from './safe.pipe';
import { DashboardSearchPipe, GenderTextPipe, SuggestionSearchPipe, TaskTemplateSearchPipe, TemplateTypePipe, WallboardSearchPipe } from './custome.pipe';

@NgModule({
    exports: [
        TranslatePipe,
        SafePipe,
        TemplateTypePipe,
        SuggestionSearchPipe,
        TaskTemplateSearchPipe,
        DashboardSearchPipe,
        GenderTextPipe,
        WallboardSearchPipe
    ],
    declarations: [
        TranslatePipe,
        SafePipe,
        TemplateTypePipe,
        SuggestionSearchPipe,
        TaskTemplateSearchPipe,
        DashboardSearchPipe,
        GenderTextPipe,
        WallboardSearchPipe
    ]
  })
  export class PipesModule { }

2. 特性模块未导入SharedModule

如果使用translate管道的组件属于特性模块(比如WallboardModule),该模块必须单独导入SharedModule才能获取管道的访问权限。检查所有用到管道的组件所在模块,确认是否导入了SharedModule。

3. ngClass绑定缺失CommonModule

ngClass属于Angular通用指令,需要所在模块导入CommonModule才能使用。虽然AppModule导入了CommonModule,但特性模块需单独导入。检查所有使用ngClass的组件所在模块,确认是否添加了CommonModule到imports数组中。

4. 依赖版本不兼容

当前使用的ngx-bootstrap@5.1.2仅支持Angular 12-14,与Angular 16不兼容,这会导致一系列指令(包括ngClass相关的绑定)异常。

升级方案:安装适配Angular 16的ngx-bootstrap版本:

npm install ngx-bootstrap@12.0.0 --save

同时检查ngx-chips@3.0.0是否兼容Angular 16,若不兼容需寻找替代方案或升级到适配版本。

内容的提问来源于stack exchange,提问作者Anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:09:52