首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有一种方法可以在每次从DOM中添加或删除组件时获得角9+生命周期挂钩?

是否有一种方法可以在每次从DOM中添加或删除组件时获得角9+生命周期挂钩?
EN

Stack Overflow用户
提问于 2021-06-08 16:54:46
回答 1查看 128关注 0票数 0

我有一个扩展面板组件。这个组件本身工作得很好。这是它的代码。

代码语言:javascript
复制
<div class="container">
  <div class="header" (click)="toggleSelf()">
    <div class="header--content">
      {{ header }}
    </div>
    <div class="header--action" [ngClass]="{ rotated: !isClosed }">
      <mat-icon svgIcon="chevron-down-filled"></mat-icon>
    </div>
  </div>

  <div class="content" *ngIf="!isClosed" [@expand]>
    <div class="content-wrapper">
      <ng-content></ng-content>
    </div>
  </div>
</div>

类型标

代码语言:javascript
复制
import { Component, Input } from '@angular/core';
import { trigger, transition, style, animate } from '@angular/animations';

@Component({
  selector: 'sky-expansion-panel',
  templateUrl: './expansion-panel.component.html',
  styleUrls: ['../../../../scss/components/accordion.scss'],
  animations: [
    trigger('expand', [
      transition(':enter', [
        style({
          height: '0',
          opacity: 0,
          overflow: 'hidden'
        }),
        animate(
          '500ms cubic-bezier(1, .14, .69, .05)',
          style({
            height: '*',
            opacity: 1,
            overflow: 'visible'
          })
        )
      ]),
       transition(':leave', [
         style({
           height: '*',
           opacity: 1,
           overflow: 'hidden'
         }),
          animate(
            '500ms cubic-bezier(1, .14, .69, .05)',
            style({
              height: '0',
              opacity: 0,
              overflow: 'hidden'
          })
        )
      ])
    ])
  ]
})

export class SkyExpansionPanelComponent {
  @Input() header: string;
  @Input() isClosed = true;

  public toggleSelf(): void {
    this.isClosed = !this.isClosed;
  }
}

实现HTML示例

代码语言:javascript
复制
<filter-panel *ngIf="toggleLogic()"
  <sky-accordion>
    <sky-expansion-panel header="General" [isClosed]="filterStatus.generalTabOpen">
      //irrelevant content
    </sky-expansion-panel>
  </sky-accordion>
</filter-panel>

当我把这个动画引入一个过滤面板时,我开始遇到麻烦,它也是隐藏的,并且用*ngIf显示。

我已经发现,当父组件隐藏扩展面板(通过隐藏过滤器面板)时,它在技术上触发: that动画,并在组件被破坏之前快速地应用样式。

通常情况下,如果我们希望扩展面板恢复到封闭状态,这不会是个问题。我们跟踪它是开着还是关着的。当打开过滤器面板时,扩展面板会记住正确的状态(通过isClosed输入)。

问题是,尽管内容是在DOM上呈现的,但出于某种原因,来自封闭状态的内联样式被应用到扩展面板中。更奇怪的是,你通常可以在开发工具中看到这样的东西-

代码语言:javascript
复制
<div class="content" style="height: 0; opacity: 0; overflow: hidden;">

如果您在打开状态下用展开面板关闭过滤器,然后重新打开它们,它实际上在dev tools中会出现如下所示。

代码语言:javascript
复制
<div class="content" style>

基本上,所有的工作正常,除了动画是内联风格,它不应该内联。

为了纠正这个问题,我尝试用状态方法来做动画。下面的语法可能会很混乱,因为我是从内存中输入的,但是您得到了它的要点。

状态逼近

代码语言:javascript
复制
animations: [
    trigger('expand', [
      state('closed', [
        style({
          height: '0',
          opacity: 0,
          overflow: 'hidden'
        }),
      ]),
      state('open', [
        style({
         height: '*',
         opacity: 1,
         overflow: 'visible'
       })
     ]),
       transition('closed => open', [
         animate( '500ms cubic-bezier(1, .14, .69, .05)')
      ]),
       transition('open => void', [
         animate('500ms cubic-bezier(1, .14, .69, .05)')
      ]),
       transition('void => open', [
         animate('500ms cubic-bezier(1, .14, .69, .05)')
      ])
    ])
  ]

状态逼近表达式

代码语言:javascript
复制
<div class="content" *ngIf="!isClosed" [@expand]="isClosed ? closed : open">

这也没有产生任何不同的结果。此时,我打算尝试在ngOnInit中设置ngOnInit的值,希望触发器会改变,但发现扩展面板中的ngOnInit和其他生命周期挂钩在页面加载时触发一次,即使过滤器甚至不在DOM上。是否有一种方法可以在每次向DOM中添加或移除它们时强制它们触发,以便我可以尝试更新这个动画的状态?

还是有人对我的问题有别的建议?现在,我只是删除离开动画,但理想情况下,我保留动画。

除了页面加载时,扩展面板中没有生命周期挂钩。

EN

回答 1

Stack Overflow用户

发布于 2021-06-08 17:04:44

奇怪的是,这种方法有什么不同吗?

代码语言:javascript
复制
<ng-container *ngIf="!isClosed">
  <div class="content" [@expand]>
    <div class="content-wrapper">
      <ng-content></ng-content>
    </div>
  </div>
<ng-container>

ngOnInitngOnDestroy

代码语言:javascript
复制
import { Component, Input, OnInit, OnDestroy } from '@angular/core';

export class SkyExpansionPanelComponent implements onInit, onDestroy{
  @Input() header: string;
  @Input() isClosed = true;

  public toggleSelf(): void {
    this.isClosed = !this.isClosed;
  }

  ngOnInit() {
    // gets fired every time the component is added 
  } 

  ngOnDestroy() {
    // gets fired every time the component is removed
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67891375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档