我在做什么我
 
有一个*ngIf基于简单布尔值隐藏/显示使用的组件.当组件变得可见时,我想将焦点应用于其模板中的子元素.
问题
 
如果我翻转布尔值,组件正确显示,但如果我尝试使用this._elRef.nativeElement.querySelector("div#test")它来获取对子元素的引用,则返回null.如果我等待几秒钟,相同的代码将返回对我所期望的元素的引用.
猜测
 
我假设在翻转布尔角后经过整个渲染周期以显示新的可见组件,并且在我querySelector()在下一行中应用时尚未完成.
我想知道的是
 
所以我想知道的是,我怎样才能确定我ngIf已经生效并且元素是他们在DOM中被选中的?
是否存在回调ngIf或者我是否可以强制视图更新并从中获取回调?
我希望这是有道理的.这是一个漫长的一天(漫长的一周),我太累了.
谢谢大家
如果它有帮助,我正在使用Angular2 v2.0.0-beta.15
Mar*_*cok 27
如果将布尔值翻转到true下一行代码中,则尝试获取对由NgIf控制的组件或DOM元素的引用......好吧,该组件或DOM元素尚不存在.Angular不会与您的代码并行运行.您的JavaScript回调必须完成,然后运行Angular(更改检测),这将注意布尔值更改并创建组件或DOM元素并将其插入DOM.
要解决您的问题,请setTimeout(callbackFn, 0)在翻转布尔值后调用.这会将您添加callbackFn到JavaScript消息队列中.这将确保Angular(更改检测)在回调函数之前运行.因此,当您callbackFn执行时,您想要聚焦的元素现在应该存在.使用setTimeout(..., 0)可确保callbackFn在下一轮JavaScript事件循环中调用您的调用.
setTimeout(..., 0)在讨论AfterView*钩子时,在LifeCycle钩子开发指南中使用这种使用技巧.
如果您需要更多详细信息,请参阅以下几个示例:
focus小智 10
这个问题相当陈旧,当时的解决方案当时可能还没有.
该setTimeout()方法完全可行,但具有显着的缺点.如果你只是设置一个类来定位一个元素,就像我一样,你得到一个跳跃的结果,因为代码是在angular循环之后执行的.
使用ChangeDetectorRef会产生不跳跃的结果.
所以不是这样的:
class Foo {
  public isDisplayed = false;
  constructor(@Inject(ElementRef) private elementRef: ElementRef) {
  }
  public someMethod(): void {
     this.isDisplayed = true;
     setTimeout(() => {
         const child = this.elementRef.nativeElement.querySelector('.child-element');
         // ...
     });
  }
}
你可以这样做:
class Foo {
  public isDisplayed = false;
  constructor(@Inject(ElementRef) private elementRef: ElementRef,
              @Inject(ChangeDetectorRef) private changeDetectorRef: ChangeDetectorRef) {
  }
  public someMethod(): void {
     this.isDisplayed = true;
     this.changeDetectorRef.detectChanges();
     const child = this.elementRef.nativeElement.querySelector('.child-element');
     // ...
  }
}
| 归档时间: | 
 | 
| 查看次数: | 11464 次 | 
| 最近记录: |