Javascript 如何获取动态创建的div的高度并将其发送给同级组件?
我有一个Javascript 如何获取动态创建的div的高度并将其发送给同级组件?,javascript,angular,typescript,twitter-bootstrap,ng-bootstrap,Javascript,Angular,Typescript,Twitter Bootstrap,Ng Bootstrap,我有一个父组件和两个子组件,如下所示 @ViewChild('carousel', {read: ElementRef, static:false}) elementView: ElementRef; ngAfterViewInit(){ console.log(this.elementView.nativeElement.offSetHeight); //throws height of created carousel first,then if next id doesnt ha
父组件
和两个子组件
,如下所示
@ViewChild('carousel', {read: ElementRef, static:false}) elementView: ElementRef;
ngAfterViewInit(){
console.log(this.elementView.nativeElement.offSetHeight);
//throws height of created carousel first,then if next id doesnt have alert still shows me the height which previously created
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes.transferredHeight.currentValue)
}
父组件.html
<child-component-1 [id]="id"></child-component-1>
<child-component-2></child-component-2>
<ngb-carousel #carousel *ngIf="alertFound" class="carousel-alert" [interval]="false" [wrap]="false"
[showNavigationIndicators]="false">
........................(Things go on here after result comes)
</ngb-carousel>
<div [style.height.px]="actualHeight"></div>
child-component-1.html
<child-component-1 [id]="id"></child-component-1>
<child-component-2></child-component-2>
<ngb-carousel #carousel *ngIf="alertFound" class="carousel-alert" [interval]="false" [wrap]="false"
[showNavigationIndicators]="false">
........................(Things go on here after result comes)
</ngb-carousel>
<div [style.height.px]="actualHeight"></div>
子组件-2.ts
alertFound;
this.service.checkAlert(id).subscribe((result:any)=>{
if(result.alertFound){
this.alertFound=true;
}
})
this.actualHeight = window.innerHeight - 269;
alertActive = new BehaviorSubject(0);
setAlertHeight(value:number){
this.alertActive.next(value)
}
有趣的是,在child-component-1
上,我试图像下面那样跟踪它
@ViewChild('carousel', {read: ElementRef, static:false}) elementView: ElementRef;
ngAfterViewInit(){
console.log(this.elementView.nativeElement.offSetHeight);
//throws height of created carousel first,then if next id doesnt have alert still shows me the height which previously created
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes.transferredHeight.currentValue)
}
它显示以前创建的carousel
高度,即使结果为false
,并且当时无法创建carousel
。我猜发生这种情况是因为结果有时来得很晚,有时速度很快。为了收听viewchild
上的检测,我找到了如下类似的东西,它完全符合我的要求,并解决了发出非创建警报高度的问题
@ViewChildren('carousel', {read: ViewContainerRef}) viewContainerRefs;
ngAfterViewInit() {
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
console.log(item._results[0]._lContainer[0][0].offsetHeight);
}
})
}
现在的问题是将这个高度发送到child-component-2,我应该在这里动态计算高度
我考虑了两个选项。第一个选项是在服务上创建主题,从child-component-1
向其发射高度,然后在child-component-2
上收听,如下所示
@ViewChild('carousel', {read: ElementRef, static:false}) elementView: ElementRef;
ngAfterViewInit(){
console.log(this.elementView.nativeElement.offSetHeight);
//throws height of created carousel first,then if next id doesnt have alert still shows me the height which previously created
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes.transferredHeight.currentValue)
}
服务.ts
alertFound;
this.service.checkAlert(id).subscribe((result:any)=>{
if(result.alertFound){
this.alertFound=true;
}
})
this.actualHeight = window.innerHeight - 269;
alertActive = new BehaviorSubject(0);
setAlertHeight(value:number){
this.alertActive.next(value)
}
子组件-1
ngAfterViewInit() {
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
this.service.setAlertHeight(item._results[0]._lContainer[0][0].offsetHeight);
}
})
}
@Output() transferHeight: EventEmitter<any> = new EventEmitter();
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
this.transferHeight.emit(item._results[0]._lContainer[0][0].offsetHeight);
}
})
子组件-2
this.alertActive.subscribe(value=>{
if(value){
this.actualHeight-=value;
}
})
@Input() transferredHeight;
ngOnInit(){
this.actualHeight-=this.transferredHeight;
}
在上面的示例中,即使未创建警报,它也会导致问题带来高度。我在控制台上从child-2
和child-1
记录订阅,并注意到child-2
打印到控制台,即使child1没有向其发送任何内容
所以我考虑了另一个选项,通过@Output将高度从child-1发送到parent,然后通过输入发送到
像下面的孩子
@ViewChild('carousel', {read: ElementRef, static:false}) elementView: ElementRef;
ngAfterViewInit(){
console.log(this.elementView.nativeElement.offSetHeight);
//throws height of created carousel first,then if next id doesnt have alert still shows me the height which previously created
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes.transferredHeight.currentValue)
}
child-1
ngAfterViewInit() {
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
this.service.setAlertHeight(item._results[0]._lContainer[0][0].offsetHeight);
}
})
}
@Output() transferHeight: EventEmitter<any> = new EventEmitter();
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
this.transferHeight.emit(item._results[0]._lContainer[0][0].offsetHeight);
}
})
这一个确实解决了我前面提到的问题。但是,如果在由于网络恢复延迟而创建child-2之后创建carousel,它将返回undefined。因此,我尝试使用ngOnChanges来侦听输入变量的更改,如下所示
@ViewChild('carousel', {read: ElementRef, static:false}) elementView: ElementRef;
ngAfterViewInit(){
console.log(this.elementView.nativeElement.offSetHeight);
//throws height of created carousel first,then if next id doesnt have alert still shows me the height which previously created
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes.transferredHeight.currentValue)
}
虽然我实现了onChanges,但这个console.log不会打印任何内容。因此,我在等待您的帮助。如果有办法侦听child-1和child-2的
viewContainerRefs.changes将是最好的情况此尝试的原因:
alertActive=newbehaviorsubject(0);
setAlertHeight(值:数字){
this.alertActive.next(值)
}
即使警报未激活,触发要设置的高度也是因为您使用了行为主体
,而不仅仅是主体
。A提供初始值(0
,在您的情况下),因此订阅服务器将在订阅后立即收到该初始值(或最新发出的值)
因此,您的做法是正确的,您只需要使用常规的主题
,因为在主题
发出之前,订阅者不会收到任何值
因此,您的服务可以如下所示:
private\u alertActive=新主题();
get alertActive():可观察{
返回此信息。_alertActive.asObservable();
}
setAlertHeight(高度:数字){
此._alertActive.next(高度);
}
(请注意,Subject
是一个私有成员,但通过getter作为可观察对象公开。一般来说,订阅者不应该访问原始主题,除非他们也从中发出值。)
您的child-2组件会像这样订阅它:
this.service.alertActive.subscribe((高度:数字)=>{
此。实际高度-=高度;
});
您使用ViewChildren
并订阅其更改
,也在正确的轨道上,但是如果您引用ElementRef
s而不是ViewContainerRef
s,可能会更简单。看起来是这样的:
从“@ng bootstrap/ng bootstrap”导入{NgbCarousel}”;
@ViewChildren(NgbCarousel,{read:ElementRef})旋转木马:QueryList;
ngAfterViewInit(){
this.carousels.changes.subscribe((els:QueryList)=>{
常量高度=els.first?els.first.nativeElement.offsetHeight:0;
this.service.setAlertHeight(高度);
});
}
使用这种方法显示它。几周前我遇到了这种问题。使用jQuery也导致显示以前创建的div元素。我还想知道如何从其他组件订阅viewContainerRefs。