Динамическое изменение положения наложения углового материала после присоединения - PullRequest
0 голосов
/ 17 января 2019

Есть несколько оверлеев, которые нужно переставить после события window-resize.

Текущая начальная конфигурация PositionStrategy имеет логику, которая зависит от внешних переменных , чтобы выровнять Overalys подобно поведению CSS Grid / Flexbox.

Эта проблема material2 , похоже, указывает на то, что можно использовать только OverlayRef.dispose() => OverlayRef.create().

Есть ли какое-либо решение, удовлетворяющее следующему:

  • Может обновить позицию с нестатическими значениями.
  • Не уничтожает экземпляр компонента.

Предпочтительно вызывать из службы, а не из OverlayRef экземпляра компонента.

Изменить 1 для ясности: Учитывая следующее PositionStrategy, OverlayRef.updatePosition(), кажется, не применяется, так как необходимо пересчитать px. * Примечание window.innerWidth

      private setChannelPosition(): PositionStrategy {
        const chatWidth = 280;
        const chatSpace = 5;
        const distanceFromEdge = 80;

        const existingModalCount = this.channelModals.size;
        const numModalsCanFit = 
           Math.floor((window.innerWidth - 2 * distanceFromEdge) / (chatWidth + chatSpace));
        const distFromRight = 
           distanceFromEdge + ((existingModalCount % numModalsCanFit) * (chatWidth + chatSpace));
        return this.overlay.position().global().bottom('0px').right(`${distFromRight}px`);
      }

Редактировать 2: Модалы временные. Таким образом, решение с flexibleConnectedTo(), похоже, не применимо, так как любой мод может быть или не быть закрыт пользователем в любом порядке.

1 Ответ

0 голосов
/ 17 января 2019

При условии, что вы набираете setChannelPosition() только один раз при наборе OverlayConfig, например:

export class MyComponent implements OnInit {

  private overlayRef: OverlayRef;

  constructor(
    private overlay: Overlay
  ) { }

  public ngOnInit(): void {
    this.createOverlay();
  }

  @HostListener('window:resize')
  public onResize(): void {
    this.overlayRef.updatePosition();
  }

  private setChannelPosition(): PositionStrategy {
    const chatWidth = 280;
    const chatSpace = 5;
    const distanceFromEdge = 80;

    const existingModalCount = this.channelModals.size;
    const numModalsCanFit =  Math.floor((window.innerWidth - 2 * distanceFromEdge) / (chatWidth + chatSpace));
    const distFromRight = distanceFromEdge + ((existingModalCount % numModalsCanFit) * (chatWidth + chatSpace));
    return this.overlay.position().global().bottom('0px').right(`${distFromRight}px`);
  }

  private createOverlay() {
    const config = new OverlayConfig({
      positionStrategy: this.setChannelPosition()
    });
    this.overlayRef = this.overlay.create(config);
    this.overlayRef.attach(/* template or component*/);
  }

}

поэтому строка this.overlay.position().global().bottom('0px').right( $ {distFromRight} px ); запускается только один раз, создавая GlobalPositionStrategy с нижним 0px и правильной шириной, равной тому, что когда-либо было значением distFromRight в то время.

OverlayRef.updatePosition() вызывает PositionStrategy.apply(), который GlobalPositionStrategy реализует и просто применяет значения css на основе своих свойств (в данном случае это значение 0px снизу, а rigth - любое значение distFromRight при запуске setChannelPosition()).

Решением было бы иметь PositionStrategy, который пересчитывает на PositionStrategy.apply().

class MyPositionStrategy implements PositionStrategy {
  public apply(): void {
    /* recalculates */
  }
}

const config = new OverlayConfig({
 positionStrategy: instanceOfMyPositionStrategy 
});

пример ерша

или

Измените PositionStrategy перед вызовом OverlayRef.updatePosition(), позвонив OverlayRef.updatePositionStrategy() новичок в угловом материале 7 Я думаю .

@HostListener('window:resize')
public onResize(): void {
  this.overlayRef.updatePositionStrategy(this.setChannelPosition());
  this.overlayRef.updatePosition();
}

Таким образом, setChannelPosition() запускается и PositionStrategy изменяется каждый раз, когда размер окна изменяется.

пример ерша

Примечание:

Было старое решение типа

@HostListener('window:resize')
public onResize(): void {
  this.overlayRef.getConfig().positionStrategy = this.setChannelPosition();
  this.overlayRef.updatePosition();
}

но getConfig().positionStrategy теперь доступен только для чтения и не работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...