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

Angular中动态设置mat-button焦点失效问题求助

问题原因

你的代码执行顺序逻辑没问题,失效是Angular变更检测机制导致的:组件类的search变量修改后,不会立刻同步更新到DOM上,需要等当前宏任务执行完成后Angular才会触发变更检测,更新按钮的disabled属性。你修改search = true后立刻调用focus(),此时DOM上的按钮还处于禁用状态,自然无法接收焦点。

解决方案

推荐使用Angular原生能力实现,符合框架最佳实践,修改步骤如下:

1. 修改TS代码

导入变更检测器和元素查询能力,手动触发变更检测后再设置焦点:

import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
import { FormControl } from '@angular/forms';

export class InputErrorsExample {
  city = new FormControl('');
  search: boolean = false;
  // 绑定模板中的搜索按钮引用
  @ViewChild('search') searchBtn!: ElementRef<HTMLButtonElement>;

  constructor(private cdr: ChangeDetectorRef) {}

  fetchCityDetails() {
    setTimeout(() => {
      // 调用服务获取城市详情
      this.search = true;
      // 手动触发变更检测,立刻更新按钮的禁用状态
      this.cdr.detectChanges();
      // 此时按钮已经启用,可正常设置焦点
      this.searchBtn.nativeElement.focus();
    }, 1000);
  }
}

2. 修改HTML代码

给按钮添加模板引用变量,供TS层查询:

<form class="example-form">
  <mat-form-field class="example-full-width" appearance="fill">
    <mat-label>City</mat-label>
    <input type="text" matInput [formControl]="city" (focusout)="fetchCityDetails()">
  </mat-form-field>

  <!-- 新增#search模板引用变量 -->
  <button #search tabindex="0" id="search" mat-raised-button color="primary" [disabled]="!search">Search</button>
</form>

替代方案

如果不想修改现有逻辑太多,也可以把focus调用放到下一个事件循环执行,等待变更检测完成:

fetchCityDetails() {
  setTimeout(() => {
    this.search = true;
    // 延迟0毫秒执行,等Angular完成DOM更新
    setTimeout(() => {
      const btn = document.getElementById('search');
      btn?.focus();
    }, 0);
  }, 1000);
}

内容的提问来源于stack exchange,提问作者ani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:00:05