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

Angular Material日期选择器首次编译报date.clone is not a function错误

Angular Material Datepicker 首次编译报 date.clone is not a function 错误解决方案

问题现象

项目使用 Angular Material Datepicker 组件搭配 @angular/material-moment-adapter 适配库,配置日期值为Moment类型后,首次编译启动时抛出ERROR TypeError: date.clone is not a function at DatePickerAdapter.clone错误;不修改任何代码重新编译后错误自动消失,功能恢复正常。

相关代码

组件文件 mode.component.ts

import moment from 'moment';
import { FormControl } from '@angular/forms';
import { Component } from '@angular/core';

@Component({
  selector: 'app-timesheet-day-mode',
  templateUrl: './mode.component.html'
})
export class TimesheetDayModeComponent {
  chosenDate = new FormControl(moment());
}

模板文件 mode.component.html

<input matInput [formControl]="chosenDate" [matDatepicker]="picker" />
<mat-datepicker #picker></mat-datepicker>

模块配置文件 app.module.ts

import { NgModule } from '@angular/core';
import { DateAdapter, MatNativeDateModule } from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatMomentDateModule, MomentDateAdapter } from "@angular/material-moment-adapter";

@NgModule({
    imports: [
        MatDatepickerModule,
        MatNativeDateModule,
        MatMomentDateModule,
    ],
    providers: [
        {
          provide: DateAdapter,
          useClass: MomentDateAdapter
        },
    ]
})
export class AppModule { }

项目依赖版本

"dependencies": {
    "@agm/core": "^3.0.0-beta.0",
    "@angular-slider/ngx-slider": "^2.0.3",
    "@angular/animations": "^11.2.10",
    "@angular/cdk": "^11.0.0",
    "@angular/common": "^11.2.10",
    "@angular/compiler": "^11.2.10",
    "@angular/core": "^11.2.10",
    "@angular/flex-layout": "^11.0.0-beta.33",
    "@angular/forms": "^11.2.10",
    "@angular/material": "^11.0.0",
    "@angular/material-moment-adapter": "^11.0.0",
    "@angular/platform-browser": "^11.2.10",
    "@angular/platform-browser-dynamic": "^11.2.10",
    "@angular/router": "^11.2.10",
    "core-js": "^3.0.0",
    "file-saver": "^2.0.5",
    "hammerjs": "^2.0.8",
    "lodash": "^4.17.21",
    "moment": "^2.29.1",
    "moment-timezone": "^0.5.33",
    "ngx-bar-rating": "^2.0.0",
    "ngx-color": "^6.0.0",
    "ngx-image-cropper": "^4.0.1",
    "ngx-input-file": "^10.0.0",
    "ngx-mask": "^12.0.0",
    "ngx-toastr": "^13.0.0",
    "ngx-ui-switch": "^10.0.0",
    "numbro": "^2.3.6",
    "rxjs": "^6.6.7",
    "tslib": "^2.0.0",
    "uuid": "^8.3.2",
    "zone.js": "^0.11.0"
}

问题根因

报错由日期适配器加载冲突+配置不规范共同导致:

  • 同时引入了MatNativeDateModule(适配原生JS Date对象)和MatMomentDateModule(适配Moment对象),两个模块都会向依赖注入容器注册自身的DateAdapter实现
  • 首次冷编译时模块加载顺序不稳定,若原生适配器优先被注入,组件传入的Moment实例不存在原生Date对象的clone方法,就会触发类型错误
  • 无修改重编译时,热更新机制调整了模块加载优先级,Moment适配器优先生效,错误就会临时消失
  • 手动重复声明MomentDateAdapter提供者、moment默认导入方式的兼容性问题,也会提升这类偶发报错的概率
  • 另外当前依赖中@angular/material、@angular/cdk、@angular/material-moment-adapter版本为11.0.0,和Angular核心库的11.2.10存在小版本差异,也可能引发编译时的兼容性问题

修复步骤

  • 从模块imports数组中移除MatNativeDateModule,两类日期适配器模块不可同时导入
  • 删除providers中手动声明的MomentDateAdapter配置,MatMomentDateModule导入后已经自动完成了适配器的注册,重复声明反而会干扰加载顺序
  • 调整moment的导入方式为命名空间导入,避免默认导入带来的实例初始化时序问题:将import moment from 'moment'修改为import * as moment from 'moment'
  • (可选)将@angular/material、@angular/cdk、@angular/material-moment-adapter三个包的版本对齐到11.2.x,和Angular核心库版本保持一致,消除小版本兼容隐患

修改后的核心模块配置参考:

import { NgModule } from '@angular/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatMomentDateModule } from "@angular/material-moment-adapter";

@NgModule({
    imports: [
        MatDatepickerModule,
        MatMomentDateModule,
    ]
})
export class AppModule { }

如果修改后仍存在偶发报错,可以在组件构造函数中强制指定适配器配置,彻底避免加载时序问题:

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import * as moment from 'moment';
import { DateAdapter } from '@angular/material/core';

@Component({
  selector: 'app-timesheet-day-mode',
  templateUrl: './mode.component.html'
})
export class TimesheetDayModeComponent {
  chosenDate = new FormControl(moment());
  
  constructor(private dateAdapter: DateAdapter<moment.Moment>) {
    // 可替换为项目实际使用的语言区域
    this.dateAdapter.setLocale('zh-CN');
  }
}

内容的提问来源于stack exchange,提问作者林敬軒

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:12:52