【问题标题】:AngularDart: is there a hook that is called when component is rendered?AngularDart:渲染组件时是否有一个钩子?
【发布时间】:2019-12-03 18:45:31
【问题描述】:

我正在尝试访问 <div> 元素上的 scrollHeightclientHeight 属性来决定是否显示“查看更多”链接:

<div #clippedContainer class="clipped">
  <some-other-component></some-other-component>
  <a class="view-more" href="...">View more</a>
</div>
.clipped {
  max-height: 600px;
  overflow: hidden;
  position: relative;
}

.view-more {
  position: absolute;
  width: 100%;
  top: 550px;
  text-align: center;
  display: none;

  .displayed {
    display: block;
  }
}
@ViewChild('clippedContainer', read: Element)
set clippedContainer(Element container) {
  if (container.scrollHeight > container.clientHeight) {
    container.querySelector('.learn-more').classes.add('displayed');
  }
}

问题是调用时 scrollHeight 为 0,因为组件尚未显示。我尝试在scheduleMicrotaskngAfterViewInit 中读取它,但它仍然为0。我发现了一个hack,它等待一秒钟让浏览器计算布局,然后访问所需的属性:

Future.delayed(Duration(seconds: 1)).then(() {
  if (container.scrollHeight > container.clientHeight) {
    container.querySelector('.learn-more').classes.add('displayed');
  }
});

但这会在内容呈现和链接出现之间引入不必要的延迟。有没有更好的方法来检测何时计算了布局并且scrollHeightclientHeight 可用?

更新:我发现部分问题在于包含&lt;div&gt; 的组件是由弹出框架动态构建的。看起来像 ngAfterViewInit 这样的钩子甚至在组件附加到 DOM 之前就被执行了。

【问题讨论】:

  • 我认为在 ngAfterViewInit 你已经渲染了元素
  • 正如我的问题中提到的,我尝试使用ngAfterViewInit,但它不起作用。在深入挖掘之后,我发现这个组件是由我们使用的弹出框架实例化的。我目前的理论是钩子在附加到 DOM 之前运行。事实上,框架内部使用NgZone.onTurnStart 反复检查Element.parent 字段何时被设置以确定何时将其添加到DOM。我在NgZone 上阅读了一些内容,并计划调查是否可以使用类似的方法,甚至添加一个钩子让弹出框架为我调用它。
  • 您能否更新问题以反映这是自定义弹出问题或添加到答案中?
  • 发布了更新。我还根据我在弹出框架中找到的代码发布了一个解决方案,但希望有人能找到更好的解决方案。

标签: angular angular-dart


【解决方案1】:

我找到了一种方法来检测组件何时附加到 DOM,但我不太喜欢这种方法,因为它非常复杂。希望有人能提出更好的解决方案。

class MyComponent {
  final NgZone _ngZone;
  final Element _hostElement;

  MyComponent(this._ngZone, this._hostElement);

  @ViewChild('clippedContainer', read: Element)
  Element container;

  void ngAfterViewInit() {
    final sub = _ngZone.onTurnStart.listen((_) {
      if (_hostElement.parent == null) return;
      sub.cancel();

      if (container.scrollHeight > container.clientHeight) {
        container.querySelector('.learn-more').classes.add('displayed');
      }
    });
  }
}

【讨论】:

    猜你喜欢
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2019-12-24
    • 1970-01-01
    • 2021-11-02
    • 2020-10-15
    • 1970-01-01
    相关资源
    最近更新 更多