2017-10-10 90 views
-1

中描述的那样工作我想要获取元素的offsetLeft,但是我得到的值不正确,除非使用setTimeout。Angular 2指令的生命周期钩子(ngAfterContentInit)不能像文档

基本上在指令中我有这样的:“生命周期挂钩后指令的内容已经完全初始化被称为”

ngAfterContentInit() { 
    console.log(this.el.nativeElement.offsetLeft); 
} 

文档指出此为ngAfterContentInit。但不是返回40px它返回8px(甚至不知道它在哪里得到8)。

任何想法,为什么它不工作?是否因为该指令的根元素不被视为该指令的一部分,只有它的孩子是?

回答

1

我认为这应该工作:

ngAfterContentInit() { 
    setTimeout(() => { 
     console.log(this.el.nativeElement.offsetLeft); 
    }); 
} 

这是因为目前ngAfterContentInit()火灾的小孩还是不能渲染 - 所以你需要给角的时间来做到这一点。

+0

它,但它也看起来非常哈克 – yodalr

+0

@yodalr,尽管它看起来的确哈克 - 它实际上是不。 :)这只是角度运作的方式。这里的要点是,你**有**在稍后的时间点看内容,一般来说这是确保你做到的最简单的方法。但是,如果您的内容取决于某些长的http请求(即您的父组件呈现后很长时间)而呈现,那么选择正确时间点的唯一可靠方法是明确与内容中的组件进行通信,并通过类似的方式询问它们意味着他们准备好了。 –

0

如果你不希望使用超时,使用AfterViewChecked这个语法:

start = true; 
..... 
ngAfterContentChecked() { 
    if (this.start){ 
     console.log(this.el.nativeElement.offsetLeft); 
    } 
    this.start = false; 
} 
+0

我认为值得注意的是,在每次后续的ngDoCheck()(如角度文档建议:https://angular.io/guide/lifecycle-hooks)后都会调用该钩子。这意味着它必须快速发展,否则会对用户界面造成巨大的负面影响。 –

+0

我必须不同意你的看法。无论如何,你会使用它或者不使用Angular。如果你在afterviewchecked中设置havel订阅或者计算,那么你在里面放的是重要的,那么是的,这不是一个好主意。此外,它受到条件“保护”。在其他方面,我非常感染evrything,并且有超时管理 – Vega

+0

我没有得到你不同意的 - 这实际上就是我所说的。 :)我的意思是这里有两件事:a)这个处理程序必须非常轻 - 正如你所认同的那样 - 因为它被称为很多,而且“测量”DOM元素有时会是相对较大的操作; b)它不止一次发射(实际上更多!),这可能不是OP想要的(这是他们想要的)。这就是我想说的,也许我没有表达得很清楚,对此抱歉。至于超时 - 我不喜欢超时,但有时我们不得不使用这些东西,因为我们没有更好的东西... –

相关问题