光标定位到校验失败的表单。光标聚焦后又迅速失焦

本文探讨了一个在Angular应用中遇到的组件通信挑战,即父组件无法直接通过ViewChild获取孙组件的情况。解决方案是通过子组件的ViewChild间接访问孙组件,并在用户取消操作时利用定时器重新聚焦到未通过验证的输入框。此外,还详细解释了如何在多个输入框中找到第一个不符合条件的输入框并进行焦点定位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

填写的赠品大于等于10,保存时,需要弹框提示用户。
用户确定则直接保存,用户点取消则不保存且光标定位到大于等于10的输入框中。

问题描述:

遇到的问题:

  1. 用viewChild拿不到孙组件,返回的是undefined。
  2. 点击保存时,会弹出模态框,点取消时,光标会定位到校验未通过的赠品输入框中,但是又迅速失焦。
  3. 赠品可以添加多个,所以赠品输入框也会有多个,取消时如何定位到校验未通过的输入框中。数据和视图找不到对应。

原因分析:

问题的分析:

  1. viewChild是父组件与子组件之间的通信方式,通过viewChild父组件可以使用子组件上的变量和方法,孙组件属于非父子的关系了,当然拿不到,返回undefined。
  2. 迅速失焦,点保存时会弹出模态框,当点击模态框中的取消时,确实focus了输入框,但是由于模态框自己有一个自动聚焦的事件,会自动聚焦到保存按钮上。所以输入框中的光标会迅速失焦。

解决方案:

具体解决方案:

  1. 用viewChild拿到子组件,而子组件用viewChild拿到孙组件,这样父组件就可以调用到孙组件中的方法。
  2. 模态框点取消时会自动聚焦到保存按钮上,所以要在取消时加上定时器,在定时器里面让光标定位到输入框。
  3. 有多个输入框时,多个输入框的值大于10,则让光标定位到第一个大于10的那个输入框。用document.querySelectorAll()找出所有的赠品输入框得到的是个nodeList,遍历nodeList找出第一个值>=10的元素,调用focus()方法。
  4. 注意:遍历这个nodeList时,要给里面的元素加上接口< HTMLInputElement >,否则拿值.value和调用方法.focus()是会报错的(报不存在该属性的错误)
<!-- 孙组件中的赠品输入框 -->
<input class="once-input" nz-input [(ngModel)]="gift.once" rule="^[1-9][0-9]*$">


<!-- 子组件 -->
<div>
	<孙组件></孙组件>
</div>


<!-- 父组件 -->
<div>
	<子组件></子组件>
</div>
// 孙组件中聚焦输入框的方法
cursorFocus() {
    const onceInput = document.querySelectorAll('.once-input');
    for (let i = 0; i < onceInput.length; i++) {
    // <HTMLInputElement>需要这个接口否则拿不到value,也不能调用focus()
      const item = (<HTMLInputElement>onceInput[i]); 
      if (+item.value >= 10) {
        item.focus();
        break;
      }
    }
  }
  
  
// 子组件中引用孙组件
 @ViewChild(PromotionDetailRuleGiftComponent, { static: false })
  giftComponent:PromotionDetailRuleGiftComponent;


// 父组件中:
// 1.引用子组件
@ViewChild(PromotionDetailRuleComponent, { static: false })
  ruleComponent: PromotionDetailRuleComponent;
// 2.调用孙组件的方法
const giftItem = spGiftList.find(v => +v.once >= 10);
if (giftItem) {
  this.modalService.confirm({
    nzTitle: this.getI18nValue('ts'),
    nzContent: `${this.getI18nValue('sfmdzs')}${giftItem.once}${this.getI18nValue('gczp')}`,
    nzOnCancel: () => {
      setTimeout(() => { // 弹框取消后会自动聚焦仅保存or提交按钮,需要定时器来重新聚焦输入框
        this.ruleComponent.giftComponent.cursorFocus(); // 调用孙组件中的光标定位的方法
      }, 500);
    },
    nzOnOk: () => {
      this.request(); // 保存时的请求
    }
  });
} else {
  this.request(); // 保存时的请求
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值