Angular集成Clarity:@fadeMove动画导致clr-modal模态框无法打开
问题描述
使用clr-modal组件打开模态框时出现以下错误:
core.mjs:6620 ERROR Error: NG05105: Unexpected synthetic listener @fadeMove.done found. Please make sure that: - Either BrowserAnimationsModule or NoopAnimationsModule are imported in your application. - There is corresponding configuration for the animation named @fadeMove.done defined in the animations field of the @Component` decorator (see https://angular.io/api/core/Component#animations).
错误提示:发现意外的合成监听器@fadeMove.done,需确保应用已导入BrowserAnimationsModule或NoopAnimationsModule,且@Component装饰器的animations字段中定义了对应@fadeMove.done的动画配置。
重现步骤
点击按钮将布尔属性deleteGroupModalOpen设为true时触发错误,模态框无法显示。
相关代码
my-component.html
<div class="clr-row clr-justify-content-end"> <div class="clr-col-1"> <button type="button" class="btn btn-icon" aria-label="home" (click)="deleteGroupModalOpen = true"> <cds-icon shape="plus-circle"></cds-icon> Add </button> </div> </div> <div class="clr-row"> <div *ngFor="let group of kcmGroups" class="clr-col-lg-3 clr-col-12"> <div class="card"> <div class="card-header"> <div class="clr-row"> <div class="clr-col clr-align-self-start"> <a [ngClass]="getLabelStyle(group.color)">Group: {{ group.name }}</a> </div> <div class="clr-col clr-align-self-end"> <button type="button" class="btn btn-icon btn-sm" aria-label="home"> <cds-icon shape="pencil"></cds-icon> </button> <button type="button" class="btn btn-icon btn-sm btn-danger" aria-label="home" > <cds-icon shape="trash"></cds-icon> </button> </div> </div> </div> <div class="card-block"> <button type="button" class="btn btn-icon btn-success" aria-label="settings"> <cds-icon shape="deploy"></cds-icon> Enter </button> </div> </div> </div> <clr-modal [(clrModalOpen)]="deleteGroupModalOpen"> <h3 class="modal-title">I have a nice title</h3> <div class="modal-body"> <p>But not much to say...</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-outline" (click)="deleteGroupModalOpen = false">Cancel</button> <button type="button" class="btn btn-primary" (click)="deleteGroupModalOpen = false">Ok</button> </div> </clr-modal> </div>
app.module.ts
import { NgModule } from "@angular/core"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { ClarityModule } from "@clr/angular"; import { AppComponent } from "./app.component"; import { BrowserModule } from "@angular/platform-browser"; @NgModule({ imports: [ BrowserModule, BrowserAnimationsModule, ClarityModule, ], declarations: [ ], bootstrap: [ AppComponent ], providers: [], }) export class AppModule { }
main.ts
import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch((err) => console.error(err));
package.json
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "kcm-angular": { "projectType": "application", "schematics": {}, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/kcm-angular", "index": "src/index.html", "browser": "src/main.ts", "polyfills": [ "zone.js" ], "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": [ "src/styles.css", "node_modules/@cds/core/global.min.css", "node_modules/@cds/core/styles/theme.dark.min.css", "node_modules/@clr/ui/clr-ui.min.css" ], "scripts": [ ] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "2kB", "maximumError": "4kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { "buildTarget": "kcm-angular:build:production" }, "development": { "buildTarget": "kcm-angular:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n" }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "polyfills": [ "zone.js", "zone.js/testing" ], "tsConfig": "tsconfig.spec.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": [ "src/styles.css" ], "scripts": [] } } } } } }
版本信息
- Clarity版本:v17.2.0
- Angular版本:18.0.4
- 设备信息:
- 操作系统:UBUNTU 20.04
- 浏览器:Chrome
解决方案
你的项目同时混用了Angular模块式架构(AppModule)和独立组件架构(bootstrapApplication),这是导致动画模块未正确加载的核心原因。Angular 18默认使用独立组件模式,main.ts中用bootstrapApplication启动应用时,AppModule中的BrowserAnimationsModule不会被加载,从而触发动画监听器错误。
修复步骤:
配置独立组件模式的动画支持
修改app.config.ts,将provideAnimations()和Clarity的独立组件提供者添加到providers数组:import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideAnimations } from '@angular/platform-browser/animations'; import { provideClarityAngular } from '@clr/angular'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideAnimations(), provideClarityAngular() ] };调整
AppComponent为独立组件
在app.component.ts中添加standalone: true,并导入所需模块:import { Component } from '@angular/core'; import { ClarityModule } from '@clr/angular'; import { CommonModule } from '@angular/common'; @Component({ selector: 'app-root', standalone: true, imports: [CommonModule, ClarityModule], templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { deleteGroupModalOpen = false; kcmGroups = []; getLabelStyle(color: string) { // 实现你的样式逻辑 return ''; } }移除无用的
AppModule
由于使用bootstrapApplication启动应用,AppModule已不再需要,可直接删除该文件。验证依赖安装
确保所有依赖都正确安装:npm install
关键说明:
- 独立组件模式下无需
NgModule,所有依赖和模块通过组件的imports数组或应用配置的providers提供。 provideAnimations()是独立模式下替代BrowserAnimationsModule的方式,必须添加才能启用Angular动画支持。
内容的提问来源于stack exchange,提问作者ahmed.toumi
相关产品推荐
相关产品推荐

