如何删除已禁用的属性和焦点输入Angular 5?

问题描述 投票:0回答:2

我有点困惑,试图集中禁用的输入。我的输入在开始时被禁用。单击按钮后,我想删除禁用attr并关注此输入。

我在焦点this.renderer.removeAttribute(this.elRef.nativeElement, 'disabled');之前从输入中删除了属性,然后尝试将焦点输入this.input.nativeElement.focus();

其中this.input@ViewChild('input') input: ElementRef;禁用属性消失,但输入没有集中。这是jsfidle我也尝试绑定到[attr.disabled],但它没有帮助。

什么是动态关注元素和操纵Angular中DOM属性的最佳解决方案?顺便说一句,我正在使用最新的Angular。

javascript html angular dom angular5
2个回答
2
投票

elRef是你没有disabled属性的宿主元素

this.renderer.removeAttribute(this.elRef.nativeElement, 'disabled');
                                   ^^^^^
                             seems input should be here

Plunker Example

更新

为什么在这种情况下输入不集中?我切换isDisabled - 所以禁用attr应设置为null,我错了吗?那么我们应该能够专注于输入

那是因为角度变化检测机制的工作原理。

它将被设置为null但仅在没有微任务的情况下在下一个VM转向之后。 Angular使用zone.js来运行更改检测。

this.isDisabled = !this.isDisabled; // 1) you only change property
this.input.nativeElement.focus();  // 2) you executed focus(input is still disabled)
....
....
AppRef
  zone.onMicrotaskEmpty.subcribe(() => run change detection) // 3) your template is updated

您有几种方法可以解决此问题:

1)使用Renderer2 API,如答案开头所示

2)订阅onMicrotaskEmpty事件Example

import { take } from 'rxjs/operators/take';

constructor(private zone: NgZone) {}

focus() {
  this.isDisabled = !this.isDisabled;

  this.zone.onMicrotaskEmpty.pipe(
    take(1)
  ).subscribe(() => {
    this.input.nativeElement.focus();
  });
}

在这种情况下,角度应用程序不会调用添加更改检测周期。

3)使用setTimeout,如另一个答案所示。

您的角度应用程序还将检查完整的组件树。

4)在另一个答案的评论中建议使用ChangeDetectorRef.detectChanges()方法。

this.isDisabled = !this.isDisabled; 
this.cdRef.detectChanges();
this.input.nativeElement.focus();

额外检查此组件及其子组件


3
投票

根本不需要渲染器,您只需要等待一个滴答,以便更新视图,因此不再禁用nativeElement并且可以集中注意力:

focus() {
   this.isDisabled = !this.isDisabled;
   setTimeout(() => {
      this.input.nativeElement.focus();
   });
}
© www.soinside.com 2019 - 2024. All rights reserved.