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

时间:2018-02-27 17:50:41

标签: javascript html angular dom angular5

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

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

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

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

2 个答案:

答案 0 :(得分:3)

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

focus() {
   this.isDisabled = !this.isDisabled;
   setTimeout(() => {
      this.input.nativeElement.focus();
   });
}

答案 1 :(得分:2)

elRef是您的主机元素,没有disabled属性

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

<强> Plunker Example

更新

  

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

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

只有在没有微任务的情况下,当下一个虚拟机转弯后,它才会被设置为null 。 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();

仅检查此组件及其子组件