【问题标题】:angular2 ng2-bootstrap collapse animation workaroundangular2 ng2-bootstrap 折叠动画解决方法
【发布时间】:2017-02-24 02:00:46
【问题描述】:

我知道由于 angular2 的指令动画支持不可用,当前 ng2-bootstrap 中的动画代码被注释掉的问题。

因此,我通过在我的组件中使用 angular2 的动画创建了一个解决方法。

animations: [
  trigger('slideMenu', [
    state('true', style({ height: '0px' })),
    state('false', style({ height: '*' })),
    transition('1 => 0', animate('200ms ease-in')),
    transition('0 => 1', animate('200ms ease-out'))
  ]),
]

更新:我有 plunker 示例:https://plnkr.co/edit/iVffRLUhzp43DXo5BYlJ?p=preview(如果加载示例失败,请多次单击停止并运行按钮。它最终会起作用)。

我希望上面的动画代码在展开时创建滑出效果,在折叠时创建滑入效果。然而,动画仅在展开时有效。当我尝试折叠菜单时,它就消失了,没有任何动画。

我想知道是否有人曾经尝试过为滑入和滑出的菜单垂直折叠创建一个可行的解决方法。

提前致谢。

【问题讨论】:

  • 如果您将一个小的 plunker 示例放在一起展示当前状态,我很高兴尝试并提供帮助 - 因为我也一直在搞乱 ng2-bootstrap。
  • @RobM 我添加了 plunker 示例:plnkr.co/edit/iVffRLUhzp43DXo5BYlJ?p=preview
  • @RobM 具有讽刺意味的是,我相信让我的动画正常工作的唯一方法是不使用 ng2-bootstrap。在我取出 [collapse]="isCollapsed()" 后,一切正常。我相信这是由于 ng2-bootstrap 在触发崩溃后立即将 css 显示属性设置为“无”。我想解决方法是为所有需要它的组件放置我的折叠动画,直到指令的动画可用为止。
  • 感谢您清楚地描述了一个有趣的问题,将 plunker 放在一起来演示该问题并在您解决问题并发现解决方法时分享您的发现(抱歉,我的反应很慢,因为我在我之后生病了第一条评论)。

标签: angular animation ng2-bootstrap


【解决方案1】:

您实际上已经弄清楚发生了什么,但我深入研究并提供了一些其他详细信息,说明您看到这些结果的原因,以及对变通方法的增强,使其更简洁和可重复使用。

根本原因:

如您所述,ng2-bootstrap 当前的折叠实现只是在display: nonedisplay: block 之间切换元素显示样式,就像您可以在see in the source 一样。对 display 属性的这种更改会使过渡动画无效(至少目前,当 display 属性更改时,浏览器不尊重过渡)。

看起来折叠实现的预期默认行为是有动画,但有一个障碍。由于用于折叠的 ng2-bootstrap 实现使用指令,因此它们正在等待 Angular 2+ 对指令动画的支持,这不存在——至少目前不存在(但在组件上支持,正如您当前使用的那样)。这是一个已知问题,已报告here

解决方法:

您表示您打算在多个地方制作动画,这表明您可以从使动画可重用中受益——这将使事情更加DRY 并且更易于管理。在您需要动画时弄乱了一堆解决方法选项后,我认为最好的方法是:

  1. 不要将 ng2-bootstrap 的 collapse 指令用于模板中需要动画进出的项目。在您的示例中,[collapse]=isCollapsed()(您已经确定)。
  2. 像现在一样在组件上指定动画。
  3. 创建一个类来定义您的动画,使其可重复使用。
  4. 将#2 中的动画设置为#3 中的相应对象。

这是一个例子:

动画.ts
import { trigger, state, transition, animate, style } from '@angular/core';

export class Animations {
    public static slideInOut = trigger('slideInOut', [
        state('true', style({ height: '0px' })),
        state('false', style({ height: '*' })),
        transition('1 => 0', animate('500ms ease-in')),
        transition('0 => 1', animate('500ms ease-out'))
    ]);
}
app.component.ts
import { Component, trigger, state, style, transition, animate } from '@angular/core';
import { Animations } from './animations';

@Component({
  selector: 'my-app',
  templateUrl: './app/app.component.html',
  styleUrls: ['./app/app.component.css'],
  animations: [ Animations.slideInOut ]
})
export class AppComponent { 
  private collapsed: boolean;

  constructor() {
    this.collapsed = true;
  }

  public isCollapsed(): boolean {
    return this.collapsed;
  }

  public setCollapsed(): void {
    this.collapsed = true;
  }

  public toggleMenu(): void {
    this.collapsed = !this.collapsed;
  }
}
app.component.html
<header>
    <nav class="navbar navbar-fixed-top" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" (click)="toggleMenu()">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
            </div>
        </div>
    </nav>

    <nav role="navigation" class="navbar-fixed-top-responsive">
        <div class="vertical-menu" [@slideInOut]="isCollapsed()">
            <ul class="menu-item">
                <li><a>menu1</a></li>
                <li><a>menu2</a></li>
                <li><a>menu3</a></li>
            </ul>
        </div>
    </nav>
</header>

【讨论】:

  • 感谢@RobM 的详细解释。这很有帮助!可重复使用的解决方法很简洁,绝对是我所期望的。我想我会坚持这种解决方法,直到 Angular 团队修复对动画的指令支持,然后 ng2-bootstrap 团队取消注释他们的代码。
  • @YangLi 我已经订阅了关于 Angular 问题/功能的通知。如果问题得到解决,我将联系 ng2-bootstrap 团队并通知他们——或者甚至可能做一些工作并向项目提交拉取请求。我希望回到这里并添加更多信息。编码愉快!
  • @RobM 这个问题有什么新的吗?似乎动画在 4.2 之后得到了升级。 Edit 看起来它正在等待此 [github.com/ng-bootstrap/ng-bootstrap/pull/1839](pull 请求中的合并。
猜你喜欢
  • 2016-12-29
  • 2018-05-22
  • 2015-01-29
  • 1970-01-01
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 2017-07-11
  • 2021-07-13
相关资源
最近更新 更多