【问题标题】:Angular renders component first then removes another in ng-IfAngular 先渲染组件,然后在 ng-If 中移除另一个组件
【发布时间】:2020-06-12 19:19:16
【问题描述】:

我使用 ngif 指令一次显示两个组件。

<app-root>
   <first-Comp *ngIf="showFirst"></first-Comp>
   <second-Comp *ngIf="!showFirst"></second-Comp>
</app-root>

要点是

  1. showFirst 变量使用 true 进行初始化。
  2. first-comp 包含一个高度为 100px 的元素;
  3. second-comp 具有动态元素

在第二个组件中,我在 document.body.scrollHeight 中使用 ngOnInit 计算高度

问题是当showFrist 变为false 时,角度首先呈现第二个comp 然后删除first-comp。结果我得到的高度是 100+ 而不是 0。但是我需要在组件渲染上只有 second-comp 的身体高度。

我认为可能不会妨碍的另一件重要的事情。即第一个和第二个组件都从角度自动变化检测中分离出来以提高性能。我有一个像这样的基础组件

export class BaseComponent {
private subscriptions: Subscription[] = [];

  constructor(private childViewRef: ChangeDetectorRef) {
      this.childViewRef.detach();
  }

  public updateUI(): void {
    try {
        this.childViewRef.reattach();
        this.childViewRef.detectChanges();
        this.childViewRef.detach();
    } catch (ex) {
        // ignored
    }
  }

  protected addSubscriptions(subs: Subscription) {
    this.subscriptions.push(subs);
  }

  protected unSubscribeSubscriptions() {
    this.subscriptions.forEach(item => item.unsubscribe());
    this.subscriptions = [];
  }
}

除了 AppComponent 之外的所有组件都继承了这个 BaseComponent 所以 SecondComp 的代码看起来是这样的。

@Component({
  selector: 'second-comp',
  templateUrl: './SecondComponent.component.html',
  styleUrls: ['./SecondComponent.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SecondComponent extends BaseComponent implements OnInit, AfterViewInit{
   constructor(private ref:ChangeDetectorRef){
     super(ref);  
   }

   ngAfterViewInit(): void {
     this.updateUi();
     this.publishHeight()
   }

   ngOnInit() {
    this.updateUi();
    this.publishHeight()
   }
}

我遇到这种意外行为有什么问题吗?

【问题讨论】:

  • 您是否尝试在 ngAfterViewInit 中计算高度?
  • 是的,我也试过了。 @ukn
  • 为什么需要那个高度?
  • 尝试使用 if else ,而不是 2 if in template
  • 确定检查@LogicBlower

标签: javascript angular angular-ng-if


【解决方案1】:

感觉好像你做错了。您可以在 second-comp 构造函数中注入 @Self,它会为您提供自身的 ElementRef(second-comp)。

constructor( @Self() private element: ElementRef ) {}

它可能不起作用,但它不会受到 first-comp 的影响

ngOnInit() {
    this.element.nativeElement.offsetHeight //the height for whatever you need it for
}

【讨论】:

  • 是的,我了解您的解决方案,但我需要正文的高度,因为我需要将该高度发送到父页面以调整运行此应用程序的 iframe 的大小。另一件事是我在第二次比较之后还有其他组件。然后我需要为 app-root 中的其余组件维护一个高度存储库。
【解决方案2】:

在 ngOnInit 中的 second-comp 中计算 setTimeout() 中的高度

 setTimeout(() => {
          //calculateHeight()  
        }, 200);

【讨论】:

    【解决方案3】:

    您应该在组件的视图完全呈现时计算高度。这意味着计算 ngAfterViewInit() 钩子内的高度。见https://angular.io/api/core/AfterViewInit

    【讨论】:

    • 嗨。谢谢。我检查过一次。但是在 ngAfterViewInit 中,当我要计算高度时,页面中仍然存在第一个组件。
    猜你喜欢
    • 2018-08-13
    • 2021-12-04
    • 2018-01-26
    • 1970-01-01
    • 2020-12-16
    • 2020-11-23
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    相关资源
    最近更新 更多