当前位置: 代码网 > it编程>前端脚本>AngularJs > Angular组件库ng-zorro-antd实现radio单选框选择

Angular组件库ng-zorro-antd实现radio单选框选择

2024年05月18日 AngularJs 我要评论
antd组件库升级之后代码不生效项目业务之前的代码设计了类似radio单选框取消选择的相关逻辑,用的是下面类似的代码实现的。但近期对ng-zorro-antd组件库升级之后,下面的代码不生效了。imp

antd组件库升级之后代码不生效

项目业务之前的代码设计了类似radio单选框取消选择的相关逻辑,用的是下面类似的代码实现的。但近期对ng-zorro-antd组件库升级之后,下面的代码不生效了。

import { component } from '@angular/core';
@component({
  selector: 'nz-demo-radio-radiogroup',
  template: `
    <nz-radio-group [(ngmodel)]="radiovalue">
      <label nz-radio (click)="click('a')" nzvalue="a">a</label>
      <label nz-radio nzvalue="b">b</label>
      <label nz-radio nzvalue="c">c</label>
      <label nz-radio nzvalue="d">d</label>
    </nz-radio-group>
  `
})
export class nzdemoradioradiogroupcomponent {
  radiovalue = 'a';
  click(value: any) {
    if (this.radiovalue === value) {
      this.radiovalue = ''
    }
  }
}

于是我到组件库源码里去找原因,并写demo打断点调试

  • 将nz-radio-group绑定的radiovalue值清空会首先走group组件下面的逻辑
writevalue(value: nzsafeany): void {
    this.value = value;
    this.nzradioservice.select(value);
    this.cdr.markforcheck();
  }
  • nz-radio 和 nz-radio-group都是共用这个nzradioservice,且组件内init时都有对selected$这个流做监听
@injectable()
export class nzradioservice {
  selected$ = new replaysubject<nzsafeany>(1);
  touched$ = new subject<void>();
  disabled$ = new replaysubject<boolean>(1);
  name$ = new replaysubject<string>(1);
  touch(): void {
    this.touched$.next();
  }
  select(value: nzsafeany): void {
    this.selected$.next(value);
  }
  setdisabled(value: boolean): void {
    this.disabled$.next(value);
  }
  setname(value: string): void {
    this.name$.next(value);
  }
}
// radio.component.ts ====> ngoninit
this.nzradioservice.selected$.pipe(takeuntil(this.destroy$)).subscribe(value => {
        const ischecked = this.ischecked;
        this.ischecked = this.nzvalue === value;
        // we don't have to run `onchange()` on each `nz-radio` button whenever the `selected$` emits.
        // if we have 8 `nz-radio` buttons within the `nz-radio-group` and they're all connected with
        // `ngmodel` or `formcontrol` then `onchange()` will be called 8 times for each `nz-radio` button.
        // we prevent this by checking if `ischecked` has been changed or not.
        if (
          this.isngmodel &&
          ischecked !== this.ischecked &&
          // we're only intereted if `ischecked` has been changed to `false` value to emit `false` to the ascendant form,
          // since we already emit `true` within the `setupclicklistener`.
          this.ischecked === false
        ) {
          this.onchange(false);
        }
        this.cdr.markforcheck();
      });
  • 当监听完值改变后,后面又执行了radio的click事件,把点击哪个radio的value值传过去了,所以之前的清空值操作就被覆盖了。
private setupclicklistener(): void {
    this.ngzone.runoutsideangular(() => {
      fromevent<mouseevent>(this.elementref.nativeelement, 'click')
        .pipe(takeuntil(this.destroy$))
        .subscribe(event => {
          /** prevent label click triggered twice. **/
          event.stoppropagation();
          event.preventdefault();
          if (this.nzdisabled || this.ischecked) {
            return;
          }
          this.ngzone.run(() => {
            // !!! again  
            this.nzradioservice?.select(this.nzvalue);
            if (this.isngmodel) {
              this.ischecked = true;
              this.onchange(true);
            }
            this.cdr.markforcheck();
          });
        });
    });
  }

解决方法

清空值的操作加settimeout 使组件库内部先执行完click后续再执行。

import { component } from '@angular/core';
@component({
selector: 'nz-demo-radio-radiogroup',
template: `
  <nz-radio-group [(ngmodel)]="radiovalue">
    <label nz-radio (click)="click('a')" nzvalue="a">a</label>
    <label nz-radio nzvalue="b">b</label>
    <label nz-radio nzvalue="c">c</label>
    <label nz-radio nzvalue="d">d</label>
  </nz-radio-group>
`
})
export class nzdemoradioradiogroupcomponent {
radiovalue = 'a';
click(value: any) {
  if (this.radiovalue === value) {
    settimeout(()=>{
      this.radiovalue = ''
    })
  }
}
}

总结

其实组件库单选radio本身是不支持取消选择的,正解应该是用checkbox实现相关的业务逻辑才对,但很久之前的业务逻辑涉及到很多地方的修改,此时再换checkbox并且换样式的话,改动的还是比较大的,就先简单解决这个问题。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com