当前位置: 首页 > wzjs >正文

哪个网站做螺丝生意好企业网页制作公司

哪个网站做螺丝生意好,企业网页制作公司,上海企业网站备案,广州做网络服装的网站在 Angular 应用开发中,实现用户点击按钮后,原地切换显示一个输入框并自动获取焦点的功能,是一个常见的交互模式。例如,搜索图标点击后变为搜索框,用户可以直接输入。然而,由于 Angular 的变更检测和 DOM 更…

在 Angular 应用开发中,实现用户点击按钮后,原地切换显示一个输入框并自动获取焦点的功能,是一个常见的交互模式。例如,搜索图标点击后变为搜索框,用户可以直接输入。然而,由于 Angular 的变更检测和 DOM 更新机制的异步性,直接在改变显示状态后立即调用元素的 focus() 方法,往往会因为元素尚未完全渲染或准备就绪而失败。

本文将探讨这一问题,并介绍如何利用 ChangeDetectorRef 来更同步地更新视图,从而实现对动态出现元素的精确聚焦。

问题再现:按钮到输入框的切换与聚焦

考虑以下 Angular 模板结构:

<main class="columns-content-area" *ngIf="DictManagerStack.empty() || DictManagerStack.exists('EntriesManagement')"><div class="columns-content-header"><h1 class="columns-content-title">{{ 'EntriesManagement' | translate }}</h1><button style="margin-left: auto; margin-right: 0.5rem;" *ngIf="!isClickGlassInDictManager"(click)="onDictManagerButtonClick('SearchButton', 'search')"class="normal-toolbar-button"><i class="fa-solid fa-magnifying-glass"></i></button><input #searchInput *ngIf="isClickGlassInDictManager" style="margin-left: auto; margin-right: 0.5rem; border: 1px solid #ccc; border-radius: 4px; padding: 1px;"(keyup.enter)="onDictManagerButtonClick('SearchButton', 'EnterSearch')" type="text"(keyup.esc)="onDictManagerButtonClick('SearchButton', 'cancelSearch')"(focusout)="isClickGlassInDictManager = false"[(ngModel)]="searchWordInDictManager" placeholder="搜索"/></div><p class="columns-content-description">{{ 'EntriesManagementDescription' | translate }}</p></main>

我们希望当点击搜索按钮时,isClickGlassInDictManager 变量变为 true,导致按钮隐藏,输入框显示。同时,我们希望新出现的输入框立即获得焦点。

一个直观的想法可能是在处理按钮点击的方法中直接改变变量并调用聚焦:

import { Component, ViewChild, ElementRef } from '@angular/core';// ... other imports@Component({ /* ... */ })
export class YourComponent {isClickGlassInDictManager = false;// 使用 @ViewChild 获取输入框的引用@ViewChild('searchInput') searchInputElement!: ElementRef;onDictManagerButtonClick(itemType: 'SearchButton' | 'EntriesManagementContent', item: any) {if (itemType === 'SearchButton') {this.isClickGlassInDictManager = !this.isClickGlassInDictManager;// 问题所在:此时输入框可能还未完全呈现在 DOM 中或未准备好if (this.isClickGlassInDictManager && this.searchInputElement) {const searchInput = this.searchInputElement.nativeElement as HTMLInputElement;searchInput.focus(); // 可能失败}}}
}

之所以会失败,是因为 Angular 的变更检测通常不会在你的事件处理函数执行的 同一刻 立即更新 DOM。当 isClickGlassInDictManager 的值改变时,Angular 会安排一次视图更新,但这个更新过程可能发生在当前 JavaScript 任务完成之后。因此,在 focus() 被调用时,@ViewChild('searchInput') 对应的元素可能还不存在于 DOM 中,或者虽然存在,但浏览器还没有完成其布局和渲染,导致 focus() 方法没有效果。

解决方案:手动触发变更检测 cdr.detectChanges()

为了解决这个问题,我们可以利用 Angular 提供的 ChangeDetectorRef 服务来手动触发一次变更检测,强制 Angular 立即更新视图,从而确保输入框在调用 focus() 之前已经出现在 DOM 中。

以下是使用 ChangeDetectorRef 的解决方案:

import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';// ... other imports@Component({ /* ... */ })
export class YourComponent {isClickGlassInDictManager = false;@ViewChild('searchInput') searchInputElement!: ElementRef;constructor(private cdr: ChangeDetectorRef) {} // 注入 ChangeDetectorRefonDictManagerButtonClick(itemType: 'SearchButton' | 'EntriesManagementContent', item: any) {if (itemType === 'SearchButton') {// 1. 改变状态,隐藏按钮,准备显示输入框this.isClickGlassInDictManager = !this.isClickGlassInDictManager;// 2. 手动触发变更检测// 这会强制 Angular 立即根据 isClickGlassInDictManager 的新值更新 DOMthis.cdr.detectChanges();// 3. 在 DOM 更新后,尝试聚焦输入框// 此时,由于 detectChanges() 已经执行,@ViewChild 应该已经获取到新创建的元素引用if (this.isClickGlassInDictManager && this.searchInputElement) {const searchInput = this.searchInputElement.nativeElement as HTMLInputElement;searchInput.focus(); // 现在聚焦操作应该能够成功}}}
}

方案解释

  1. this.isClickGlassInDictManager = !this.isClickGlassInDictManager;: 这一步改变组件状态,指示输入框应该显示(如果之前是隐藏的)。
  2. this.cdr.detectChanges();: 这是关键步骤。它告诉 Angular 立即执行一次变更检测。Angular 会检查所有绑定,发现 isClickGlassInDictManager 的变化,并根据 *ngIf="isClickGlassInDictManager" 的条件,同步地在 DOM 中创建并插入搜索输入框元素。
  3. if (this.isClickGlassInDictManager && this.searchInputElement): 在 detectChanges() 执行后,@ViewChild('searchInput') 应该已经成功获取到了新创建的输入框元素的引用。这个条件确保只有当输入框确实应该显示且引用可用时,才执行聚焦操作。
  4. searchInput.focus();: 由于 detectChanges() 已经保证了输入框元素的存在,这里的 focus() 调用现在能够成功地作用于实际的 DOM 元素,使其获得焦点。

通过 cdr.detectChanges(),我们将原本可能稍后发生的 DOM 更新提前到当前方法的执行流程中,从而解决了状态改变与 DOM 准备好进行交互之间的时序不同步问题。

总结

利用 ChangeDetectorRefdetectChanges() 方法,我们可以强制 Angular 立即更新视图,确保目标元素在 DOM 中存在且可供操作,从而实现对动态出现元素的精确控制,例如自动聚焦。

http://www.dtcms.com/wzjs/547915.html

相关文章:

  • 前端ui设计是什么广州seo外包
  • 做企业网站宁波企业建站程序
  • 淘宝上做网站可信吗北京网站设计公司排行榜
  • 建立手机也可浏览的网站教程网站自助建站系统
  • Wordpress 报表的插件全能优化大师
  • html网站列表怎么做德州建设公司网站
  • 网站建设责任分解现在什么语言做网站最好
  • 海报设计网站免费微信网站开发怎么做
  • 申请域名之后如何做网站石家庄网站建设咨询薇
  • 重庆市建筑工程信息官方网站网站建设代理成本
  • 网站pc和手机端怎么验证网站
  • 如何用织梦做网站详细教程微网站 获取手机号
  • 大型网站维护费一年多少单一产品网站如何做seo
  • 西部数码 网站管理手机端官网设计
  • 专业建站模板做网站样式模板
  • 网站菜单素材广告联盟接广告
  • 网站根域名是什么网站开发工具
  • 东莞长安网站设计公司wordpress搬运小红书内容
  • 一级a做爰片 A视频网站做网站的公司济南赛博科技市场
  • 海外转运网站建设资讯wordpress主题
  • 衡阳电商网站建设注册个公司要多少钱
  • 网页模板网站都有什么作用天河区发布
  • 中国制造网注册网站免费注册全国企业信用信息公示系统浙江
  • wordpress怎么管理首页侧边栏南宁网站建设公司seo优化
  • 仿帝国网站源码嘉兴网络公司变更
  • 宁波网站建设团队贺州网站建
  • 流行网站开发框架注册上海公司
  • xampp配置多网站建设公司logo图片大全
  • 官方网站建设流程及费用怎样做旅游公司的网站
  • 广州做手机网站信息免备案做网站可以盈利吗