Angular - 如何用正确的 Angular 代码替换这个 jQuery 状态变化?

Angular - how to replace this jQuery state change with correct Angular code?

在一个组件中,我有一个触发 .next(value) 的主题,它触发了这个 jQuery 逻辑:

  if (this.isOpen) {
    jQuery(`#preview-${this.index}`).
      stop().slideDown('fast');
  } else {
    jQuery(`#preview-${this.index}`).
      stop().css('display', 'block').slideUp('fast');
  };

你可以看到它以一个 id 为目标,所以我知道我必须用 @ViewChild 装饰器结构替换它。

如何将@ViewChild 与 scss 关键帧结合使用来实现相同的功能,以便删除 JQuery。

由于这是一个非常简单的 CSS 过渡,我正在寻找一种无需使用 angular 动画库即可执行此操作的方法(除非那是唯一的方法)。

备注 我发现 AngularJS here 提出并回答了相同的问题,但 Angular 没有(无论如何!)

在完成这项工作时遇到了几个问题:

  1. 请注意,代码最后应用 'display:none' 来隐藏元素。 jQuery 在动画结束后应用。所以这里的问题是你不能为 display:none 设置动画(很明显,因为那里什么都没有!)。 帮助我理解了这一点。

  2. jQuery slidedown 只是为元素的高度设置动画,使其变为 0。

有了这些知识,事情就变得很容易了。先设置两个状态css类和动画:

.fb-card-open {
  display: block;
}
.fb-card-closed {
  display: block;
  overflow: hidden;
  animation: slideup;
  padding-top: 0;
  padding-bottom: 0;
  animation-duration: 0.3s;
  animation-fill-mode: forwards;
}
@keyframes slideup {
  0% { height:inherit; }
  100% { height:0; }
}

这意味着我们有 100% 的打开状态和关闭状态,这基本上将高度设置为 0 并删除了顶部和底部的填充(因为动画元素内有填充文本,所以即使高度为 0,你仍然会看到一些垂直 space)

然后使用[ngClass]指令在两者之间切换类:

[ngClass]="{'fb-card-open': isOpen, 'fb-card-closed' : !isOpen }"

感谢this article帮助理解如何做到这一点(文章是关于AngularJS,而不是Angular,但原理与[ngClass]指令相同行为相同)

备注 如果你设置 padding:0 而不仅仅是顶部和底部,你会为元素的子元素获得一个很酷的 'fly-in' 效果,这是我通过这样做发现的一个很好的奖励!