gpt4 book ai didi

javascript - Angular 如何获取动态创建的 div 的高度并将其发送到兄弟组件?

转载 作者:行者123 更新时间:2023-12-03 06:55:04 25 4
gpt4 key购买 nike

我有一个父组件2个子组件,如下所示

Parent-component.html

<child-component-1 [id]="id"></child-component-1>
<child-component-2></child-component-2>

child-component-1 具有 ngb-carousel 组件,用于向用户显示警告和警报。由于 id 及其 result,正在创建此组件 来自 API 如下所示

child-component-1.ts

alertFound;

this.service.checkAlert(id).subscribe((result:any)=>{
if(result.alertFound){
this.alertFound=true;
}
})

child-component-1.html

<ngb-carousel #carousel *ngIf="alertFound" class="carousel-alert" [interval]="false" [wrap]="false"
[showNavigationIndicators]="false">
........................(Things go on here after result comes)
</ngb-carousel>

child-component-2中,我需要获取这个ngb-alertheight来进行屏幕动态高度计算.如果它存在,我需要从window.innerheight中减去它。

child-component-2.html

<div [style.height.px]="actualHeight"></div>

child-component-2.ts

this.actualHeight = window.innerHeight - 269;

有趣的是在 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
}

它显示以前创建的 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,我应该在其中动态计算高度。

我考虑了 2 个选项。第一个是在服务上创建主题,从 child-component-1 向它发射高度并在 child-component-2 上收听它如下图

service.ts

  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);
}
})
}

子组件-2

this.alertActive.subscribe(value=>{
if(value){
this.actualHeight-=value;
}
})

在上面的例子中,它会导致问题带来高度,即使没有创建警报。我在控制台上从 child-2child-1 和注意到 child-2 打印到控制台,即使 child1 没有向它发出任何东西。

所以我考虑了另一种选择,通过@Output 将高度从 child-1 发送到父级,然后通过 Input 发送到child2 如下所示

child-1

  @Output() transferHeight: EventEmitter<any> = new EventEmitter();
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
this.transferHeight.emit(item._results[0]._lContainer[0][0].offsetHeight);
}
})

parent

    <child-component-1 (transferHeight)="transferedHeight($event)" [id]="id"></child-component-1>
<child-component-2 [transferredHeight]="transferredHeight"></child-component-2>
alertHeight;
transferedHeight(comingHeight){
this.alertHeight=comingHeight;
}

child-2

  @Input() transferredHeight;
ngOnInit(){
this.actualHeight-=this.transferredHeight;
}

这个确实解决了我之前提到的问题。但是如果由于网络延迟而在 child-2 创建之后创建轮播,它返回未定义。因此我尝试使用 ngOnChanges 来监听输入变量的变化,如下所示

   ngOnChanges(changes: SimpleChanges) {
console.log(changes.transferredHeight.currentValue)
}

虽然我实现了 onChanges,但这个 console.log 没有打印任何东西。所以我在等待你的帮助。如果有办法从 child-2 中监听 child-1 的 viewContainerRefs.changes 将是最好的案例

最佳答案

这次尝试的原因:

alertActive = new BehaviorSubject(0);
setAlertHeight(value:number){
this.alertActive.next(value)
}

即使警报未处于事件状态也会触发要设置的高度是因为您使用了 BehaviorSubject而不仅仅是一个Subject . BehaviorSubject提供初始值(在您的情况下为 0),因此订阅者将在订阅后立即收到该初始值(或最新发出的值)。

所以你在正确的轨道上,你只需要使用常规 Subject相反,因为那时订阅者将不会收到任何值,直到 Subject发出。

因此您的服务可能如下所示:

private _alertActive = new Subject<number>();
get alertActive(): Observable<number> {
return this._alertActive.asObservable();
}

setAlertHeight(height: number) {
this._alertActive.next(height);
}

(请注意,Subject 是一个私有(private)成员,但通过 getter 作为 Observable 公开。一般来说,订阅者不应该访问原始 Subject,除非他们也从它发出值。)

你的 child-2 组件会像这样订阅它:

this.service.alertActive.subscribe((height: number) => {
this.actualHeight -= height;
});

您使用 ViewChildren 也走在了正确的轨道上并订阅其 changes , 但如果您引用 ElementRef 可能会更简单s 而不是 ViewContainerRef秒。看起来像这样:

import { NgbCarousel } from "@ng-bootstrap/ng-bootstrap";

@ViewChildren(NgbCarousel, { read: ElementRef }) carousels: QueryList<ElementRef>;


ngAfterViewInit() {
this.carousels.changes.subscribe((els: QueryList<ElementRef>) => {
const height = els.first ? els.first.nativeElement.offsetHeight : 0;
this.service.setAlertHeight(height);
});
}

Here's a StackBlitz展示它如何使用这种方法。

关于javascript - Angular 如何获取动态创建的 div 的高度并将其发送到兄弟组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64604127/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com