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

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不会被加载,从而触发动画监听器错误。

修复步骤:

  1. 配置独立组件模式的动画支持
    修改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()
      ]
    };
    
  2. 调整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 '';
      }
    }
    
  3. 移除无用的AppModule
    由于使用bootstrapApplication启动应用,AppModule已不再需要,可直接删除该文件。

  4. 验证依赖安装
    确保所有依赖都正确安装:

    npm install
    

关键说明:

  • 独立组件模式下无需NgModule,所有依赖和模块通过组件的imports数组或应用配置的providers提供。
  • provideAnimations()是独立模式下替代BrowserAnimationsModule的方式,必须添加才能启用Angular动画支持。

内容的提问来源于stack exchange,提问作者ahmed.toumi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:17:32