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

Angular 12 自定义封装mat-radio-group后ngModel绑定与change事件失效

Angular12自定义封装mat-radio组件双向绑定失效解决方案

问题根因

Angular 8+版本对Angular Material的单选组件依赖注入逻辑做了调整,原生mat-radio-button默认只会查询直接父层级的MatRadioGroup实例。你封装的my-radio-button是独立组件,内部的原生mat-radio-button和外层自定义的my-radio-group之间隔了一层自定义组件宿主,无法自动建立关联,所以选中状态无法同步到外层group,导致双向绑定和change事件失效。

具体修改方案

1. 调整my-radio-button.component.ts

注入父级MyRadioGroupComponent,手动将内部原生单选按钮注册到父group中,建立两者的关联关系:

import { Component, Input, ViewChild, OnInit, OnDestroy, Host, Optional, SkipSelf } from '@angular/core';
import { MatRadioButton } from '@angular/material/radio';
import { MyRadioGroupComponent } from './my-radio-group.component';

@Component({
    selector: "my-radio-button",
    templateUrl: "./my-radio-button.component.html"
})
export class MyRadioButtonComponent implements OnInit, OnDestroy {

    @Input() value: any;
    @Input() disabled: boolean | undefined;
    // 获取内部原生mat-radio-button实例
    @ViewChild(MatRadioButton) nativeRadio!: MatRadioButton;

    constructor(
        // 注入父级自定义radio group
        @Optional() @Host() @SkipSelf() private radioGroup: MyRadioGroupComponent
    ) {}

    ngOnInit() {
        if (this.radioGroup) {
            // 将原生单选按钮注册到父group的管理列表
            this.radioGroup._radios.push(this.nativeRadio);
            // 给原生单选按钮绑定父group关联
            this.nativeRadio.radioGroup = this.radioGroup;
        }
    }

    ngOnDestroy() {
        // 组件销毁时从父group移除,避免内存泄漏
        if (this.radioGroup) {
            const index = this.radioGroup._radios.indexOf(this.nativeRadio);
            if (index > -1) {
                this.radioGroup._radios.splice(index, 1);
            }
        }
    }
}

2. (可选)简化方案

如果不需要自定义组件的额外逻辑,可以直接把my-radio-button改成属性型指令,直接挂载在原生mat-radio-button上,不需要处理层级注入问题,性能更好也更稳定:

@Directive({
  selector: 'mat-radio-button[myRadioButton]'
})
export class MyRadioButtonDirective extends MatRadioButton {
  // 自定义逻辑直接加在这里即可
}

使用时直接写<mat-radio-button myRadioButton [value]="1">选项1</mat-radio-button>即可。

修改完成后重新运行项目,ngModel双向绑定和change事件就可以正常触发了。

内容的提问来源于stack exchange,提问作者Hưng Triệu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 16:00:02