使用Angular7开发一个Radio组件

33次阅读

共计 2063 个字符,预计需要花费 6 分钟才能阅读完成。

一、准备工作

Angular7(以下简称 ng7), 已经跟之前版本大有不同。新建工程后,可方便创建 library(简称 lib),lib 是什么呢?就是一个 npm 包的源码包。npm 作为强大的包管理器,已经成为很多 FEer 分享智慧成果的法器。本文主要介绍本人写的一个 radio 组件。

二、开发组件 radio 过程

1、使用 ng cli, 新建工程,创建 lib

// 安装 ng cli
npm install -g @angular/cli
// 新建工程
ng new ng-project
// 进入 ng-project  创建一个 lib
ng generate library radio

2、生成结构如图所示 接下来开始写组件

3、radio 结构如下

<!-- 说明:这其实是一个 radio-group 因为 radio 一般都是分组使用,这里有几个注意点
1、组内 radio 的 name 属性保持一致、组外保持唯一
2、通过 checked 属性来设置 radio 的选中状态,一定不要写成 [attr.checked]-->
<div class="input-wrap" [class.hor]="horizontal">
    <div class="custom-radio" *ngFor="let item of data; let i=index">
        <input #input class="custom-input" [name]="name" id="{{'radio_'+name+i}}" type="radio"
        [value]="item.value" (click)="clickHandler(item.value)" [checked]="item.value === value" 
        [disabled]="disabled">
        <label class="custom-label" for="{{'radio_'+name+i}}">{{item.name}}</label>
    </div>
</div>

4、radio 组件主体代码如下

export class RadioGroupComponent implements ControlValueAccessor {

    /* radio 数组 */
    @Input()
    data: Radio[] = [];

    /* radio 类型   原生或者按钮类型 */
    @Input()
    type: string;

    /* name 标识 */
    @Input()
    name: string = this.idSer.generate().replace(/-/g, '_');

    /* 水平排列 */
    @Input()
    horizontal: boolean;

    /* 禁用 */
    @Input()
    disabled: boolean;

    /* radio 值 */
    @Input() value: any;

    constructor(private idSer: IdService) { }

    clickHandler(val: any) {
        this.value = val;
        // 更改 control 的值
        this.controlChange(this.value);
        this.controlTouch(this.value);
    }


    writeValue(value: any): void {this.value = value;}

    registerOnChange(fn: Function): void {this.controlChange = fn}

    registerOnTouched(fn: Function): void {this.controlTouch = fn}

    private controlChange: Function = () => {}
    private controlTouch: Function = () => {}

}
说明:其实组件代码不是很多,但是应该注意到,我们继承了 ng 的一个 interface ControlValueAccessor,这里我觉的是比较值得侃的地方。

这是 ng 的一个 forms API, 可以方便原生 DOM 和 ng forms 传值。在组件元数据中这样定义

@Component({
    selector: 'radiogroup',
    templateUrl: './radiogroup.component.html',
    providers: [{
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => RadioGroupComponent),
        multi: true,
    }]
})
其中,这里面有两个重要的方法需要 overwrite, 不错,就是 registerOnChange 和 registerOnTouched,这两个方法在 angular 中是这样定义和使用

他们分别是在 formcontrol 的 updateOn(这个属性可以自定义)属性值为 change 或者 blur 的时候调用。因此,我们在重写这两个方法的时候应该

注意,是重写一个还是都要重写。本组件两个方法都重写了,因为值变更的时机自定义成了 blur。

三、这就是我的关于 radio 组件的封装开发,还请各位大牛朋友们多多指点,后续会继续推出关于 Angular 的开发以及研究。

正文完
 0