Angular 15中mat-slide-toggle的[disabled]属性失效问题咨询
核心原因
这个问题本质是Angular 15 及对应版本 Angular Material 的初始化逻辑/变更检测策略调整,导致 mat-slide-toggle 的 [disabled] 绑定在组件初始化阶段未被正确应用,具体分两种情况:
Material 组件内部初始化时机变化
Angular Material 15 对mat-slide-toggle的初始化流程做了优化,组件在构造或ngOnInit阶段不会同步读取disabled输入属性的初始值,而是依赖后续的变更检测周期触发更新。如果你的绑定变量是在组件初始化后期(比如ngAfterViewInit)才赋值,或者初始赋值没有触发变更检测,控件就会保持默认的启用状态,直到手动交互触发组件内部的状态更新。Angular 15 变更检测的严格性提升
Angular 15 对 Ivy 编译器的变更检测逻辑做了优化,尤其是 OnPush 组件的检测触发条件更严格。如果你的组件使用了ChangeDetectionStrategy.OnPush,且初始化时disabled绑定的变量是同步赋值但未触发引用变化(比如基本类型赋值),旧版本 Angular 可能会额外触发一次检测,而 Angular 15 则会跳过这次检测,导致初始状态未生效。
结合场景验证
你提供的两个版本示例(旧版本正常、Angular 15 失效)正好对应这个差异:旧版本的 Angular/Material 会在组件初始化时强制同步应用 disabled 属性,而 Angular 15 则遵循更严格的变更检测流程,只有当绑定变量的变更被检测到时才会更新控件状态——手动切换操作恰好触发了组件内部的变更检测,才让 disabled 属性生效。
临时方案的逻辑本质
你用的临时方案(比如手动触发变更检测、提前在构造函数赋值、用 setTimeout 延迟赋值)本质都是强制触发一次变更检测,让 mat-slide-toggle 读取到 disabled 的初始值,弥补了 Angular 15 初始化流程中缺少的同步检测步骤。
内容的提问来源于stack exchange,提问作者MichaelSun

