Вы фактически уже поняли, что происходит, но я углубился и получил некоторые дополнительные сведения о том, почему вы видели эти результаты, и усовершенствование обходного пути, который немного чище и может использоваться повторно.
Первопричина:
Как вы заметили, текущая реализация сворачивания ng2-bootstrap просто переключает стиль отображения элементов между display: none
и display: block
, как вы можете см. в источнике. Это изменение свойства display аннулирует анимацию перехода (по крайней мере, в настоящее время браузеры не учитывают переход при изменении свойства display).
Похоже, что предполагаемое поведение по умолчанию для реализации сворачивания состоит в том, чтобы иметь анимацию, но есть загвоздка. Поскольку реализация ng2-bootstrap для сворачивания использует директивы, они ждут поддержки Angular 2+ для анимации в директивах, которой пока нет — по крайней мере, (но есть в компонентах, которые вы сейчас используете). Это известная проблема, о которой сообщалось здесь.
Обходной путь:
Вы указали, что намерены иметь анимацию в нескольких местах, что предполагает, что вы могли бы извлечь выгоду из повторного использования анимации, что сделало бы вещи более СУХОЙ и проще в управлении. После того, как я повозился с кучей обходных путей, когда вам нужна анимация, я думаю, что лучше всего:
- Не используйте директиву сворачивания ng2-bootstrap для элементов в вашем шаблоне, которые вам нужно анимировать. В вашем примере
[collapse]=isCollapsed()
(как вы уже определили).
- Укажите анимацию на компонентах, как сейчас.
- Создайте класс для определения ваших анимаций, делая их повторно используемыми.
- Установите анимацию из #2 на соответствующий объект из #3.
Вот пример:
animations.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>
person
RobM
schedule
23.02.2017