【问题标题】:Angular Animation not working with Input-Output Child component角度动画不适用于输入输出子组件
【发布时间】:2020-10-15 20:52:39
【问题描述】:

我查看了 Angular 文档和一些教程,但没有解决我的问题。

我有一个子组件 accordeon 用于许多其他组件。 在 accordeon 中,它从使用它的组件接收一个布尔值,以知道何时必须打开或关闭它。 Accordeon也分为两个ng-content,一个获取父组件给定的标题,另一个获取父组件的内容。

这里是手风琴的 HTML:

<div class="d-flex jc-between ai-center p-s" (click)="toggleAccordeon();" [ngClass]="specialAccordeon ? 'accordeon' : 'special-accordeon'">
  <ng-content select="[slot=title]"></ng-content>
  <span class="icon-chevron_bottom" [ngClass]="accordeonOpened ? 'rotation_180' : ''"></span>
</div>
<ng-content [@openCloseAccordeon]=animateAccordeon select="[slot=content]" [ngStyle]="accordeonOpened && {'display': 'none'}"></ng-content>

手风琴的.ts文件:

import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { state, style, transition, animate, trigger } from '@angular/animations';

@Component({
  selector: 'srp-accordeon',
  templateUrl: './accordeon.component.html',
  styleUrls: ['./accordeon.component.scss'],
  animations: [
    trigger('openCloseAccordeon', [
      state('initial', style({
        display: 'none',
      })),
      state('final', style({
        display: 'block',
      })),
      transition('initial => final', [
        animate('1s')
      ]),
      transition('final => initial', [
        animate('2s')
      ]),
    ]),
  ]
})
export class AccordeonComponent implements OnInit {

  accordeonOpened = false;
  animateAccordeon = 'initial';
  @Output() open: EventEmitter<any> = new EventEmitter();
  @Output() close: EventEmitter<any> = new EventEmitter();
  @Output() openAccordeon: EventEmitter<any> = new EventEmitter();
  @Output() closeAccordeon: EventEmitter<any> = new EventEmitter();

  @Input() specialAccordeon;

  public toggleAccordeon(): void {
    this.animateAccordeon = this.animateAccordeon === 'initial' ? 'final' : 'initial';
    this.accordeonOpened = !this.accordeonOpened;
    if (this.accordeonOpened) {
      this.open.emit(true);
    } else {
      this.close.emit(false);
    }
    if (this.animateAccordeon === 'initial') {
      this.closeAccordeon.emit('initial');
    } else {
      this.openAccordeon.emit('final');
    }
  }

  constructor() { }

  ngOnInit() {
  }

}

使用它的父组件,order-delivery,有趣的 HTML 部分:

目前我使用 ng-class 管理打开和关闭,放置 [@openCloseAccordeon]=animateAccordeon 不起作用。

<srp-accordeon [specialAccordeon]="true" (close)="accordeonOpened = false" (open)="accordeonOpened = true" (closeAccordeon)="animateAccordeon = 'initial'" (openAccordeon)="animateAccordeon = 'final'">
    <ng-container slot="title">{{currentOrder.statusLabel}} {{(!currentOrder.isCanceled ? currentOrder.isDeliveryAtHome ? 'order.atHome' : 'order.inWithdrawalPoint' : string.Empty) | translate}}</ng-container>
    <ng-container slot="content">
        <div class="order-delivery__details mb-s" [ngClass]="accordeonOpened ? 'accordeon-opened' : 'accordeon-closed'">

总结一下。当用户单击 . 我想我错过了一些东西,从 order-delivery 传递给 accordeon 组件的数据,但没有得到什么。

感谢您的帮助。

【问题讨论】:

标签: javascript angular typescript animation angular-animations


【解决方案1】:

最终我找到了如何让它发挥作用。

accordeon.html:

<div class="d-flex jc-between ai-center p-s" (click)="toggleAccordeon(); toggleAnimation();" [ngClass]="specialAccordeon ? 'accordeon' : 'special-accordeon'">
  <ng-content select="[slot=title]"></ng-content>
  <span class="icon-chevron_bottom" [ngClass]="accordeonOpened ? 'rotation_180' : ''"></span>
</div>
<div [@openCloseAccordeon]=animateAccordeon>
  <ng-content select="[slot=content]"></ng-content>
</div>

accordeon.ts:

import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { state, style, transition, animate, trigger } from '@angular/animations';

@Component({
  selector: 'srp-accordeon',
  templateUrl: './accordeon.component.html',
  styleUrls: ['./accordeon.component.scss'],
  animations: [
    trigger('openCloseAccordeon', [
      state('initial', style({
        opacity: '0',
      })),
      state('final', style({
        opacity: '1',
      })),
      transition('initial => final', [
        animate('1s')
      ]),
      transition('final => initial', [
        animate('2s')
      ]),
    ]),
  ]
})
export class AccordeonComponent implements OnInit {

  accordeonOpened = false;
  animateAccordeon = 'initial';

  @Output() open: EventEmitter<any> = new EventEmitter();
  @Output() close: EventEmitter<any> = new EventEmitter();

  @Input() specialAccordeon;

  public toggleAccordeon(): void {
    this.accordeonOpened = !this.accordeonOpened;
    if (this.accordeonOpened) {
      this.open.emit(true);
    } else {
      this.close.emit(false);
    }
  }

  public toggleAnimation() {
    this.animateAccordeon = this.animateAccordeon === 'initial' ? 'final' : 'initial';
  }

  constructor() { }

  ngOnInit() {
  }
}

无需在父组件中指定某些内容。 一想到要记住,动画不能在 ng-content 上触发,这就是我添加一个 div 包装它的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多