обходной путь анимации коллапса angular2 ng2-bootstrap

Мне известно о том, что в настоящее время код анимации в ng2-bootstrap закомментирован из-за недоступности поддержки анимации директивы angular2.

Поэтому я создал обходной путь, используя анимацию 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 (Если не удалось загрузить пример, нажмите кнопку «Стоп и запуск» несколько раз. В конце концов это сработает).

Я хочу, чтобы приведенный выше код анимации создавал эффект выпадения при расширении и эффект скольжения при сворачивании. Однако анимация работает только при расширении. Когда я пытаюсь свернуть меню, оно просто исчезает без анимации.

Мне интересно, пытался ли кто-нибудь когда-нибудь создать рабочий обходной путь для свертывания меню по вертикали как для слайдов, так и для слайдов.

Заранее спасибо.


person AttitudeL    schedule 17.02.2017    source источник
comment
Я буду рад помочь, если вы соберете крошечный пример plunker, демонстрирующий текущее состояние — как я возиться с ng2-bootstrap тоже.   -  person RobM    schedule 17.02.2017
comment
@RobM Я добавил пример плункера: plnkr.co/edit/iVffRLUhzp43DXo5BYlJ?p=preview   -  person AttitudeL    schedule 17.02.2017
comment
@RobM По иронии судьбы я считаю, что единственный способ заставить мою анимацию работать — это не использовать ng2-bootstrap. После того, как я удалил [collapse]=isCollapsed(), все работает. Я полагаю, что это связано с тем, что ng2-bootstrap устанавливает для свойства отображения css значение none, как только срабатывает коллапс. Я предполагаю, что работа заключается в том, чтобы поместить анимацию моего сворачивания для всех компонентов, которые в ней нуждаются, до тех пор, пока анимация для директивы не станет доступной.   -  person AttitudeL    schedule 18.02.2017
comment
Спасибо за четко описанный, интересный вопрос, за сборку плунжера для демонстрации проблемы и за то, что вы поделились своими выводами, когда вы работали над вещами и нашли обходной путь (извините, мой ответ был медленным, так как я заболел после моего первого комментария).   -  person RobM    schedule 24.02.2017


Ответы (1)


Вы фактически уже поняли, что происходит, но я углубился и получил некоторые дополнительные сведения о том, почему вы видели эти результаты, и усовершенствование обходного пути, который немного чище и может использоваться повторно.

Первопричина:

Как вы заметили, текущая реализация сворачивания ng2-bootstrap просто переключает стиль отображения элементов между display: none и display: block, как вы можете см. в источнике. Это изменение свойства display аннулирует анимацию перехода (по крайней мере, в настоящее время браузеры не учитывают переход при изменении свойства display).

Похоже, что предполагаемое поведение по умолчанию для реализации сворачивания состоит в том, чтобы иметь анимацию, но есть загвоздка. Поскольку реализация ng2-bootstrap для сворачивания использует директивы, они ждут поддержки Angular 2+ для анимации в директивах, которой пока нет — по крайней мере, (но есть в компонентах, которые вы сейчас используете). Это известная проблема, о которой сообщалось здесь.

Обходной путь:

Вы указали, что намерены иметь анимацию в нескольких местах, что предполагает, что вы могли бы извлечь выгоду из повторного использования анимации, что сделало бы вещи более СУХОЙ и проще в управлении. После того, как я повозился с кучей обходных путей, когда вам нужна анимация, я думаю, что лучше всего:

  1. Не используйте директиву сворачивания ng2-bootstrap для элементов в вашем шаблоне, которые вам нужно анимировать. В вашем примере [collapse]=isCollapsed() (как вы уже определили).
  2. Укажите анимацию на компонентах, как сейчас.
  3. Создайте класс для определения ваших анимаций, делая их повторно используемыми.
  4. Установите анимацию из #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
comment
Спасибо за подробное объяснение @RobM. Это очень полезно! Многоразовое обходное решение аккуратное и определенно то, что я ожидал. Думаю, я буду придерживаться этого обходного пути, пока команда angular не исправит директивную поддержку анимации, а затем команда ng2-bootstrap не раскомментирует свой код. - person AttitudeL; 24.02.2017
comment
@YangLi Я подписался на уведомления об этой проблеме/функции Angular. Если это будет решено, я свяжусь с командой ng2-bootstrap и уведомлю их — или, может быть, даже поработаю над этим и отправлю запрос на перенос в проект. Я ожидаю вернуться сюда и добавить больше информации тогда. Удачного кодирования! - person RobM; 24.02.2017
comment
@RobM Есть что-нибудь новое по этому вопросу? Похоже, анимация получила обновление после 4.2. Edit Похоже, он ожидает слияния в этом [github.com/ng-bootstrap/ng-bootstrap/pull/1839](pull запрос). - person Kesarion; 10.11.2017