Отменяемый компонент @Ouput EventEmitter? - PullRequest
0 голосов
/ 07 марта 2019

Если у меня есть пользовательский угловой компонент, скажем, MyPanelComponent / <my-panel> как я могу реализовать функциональность, когда, если что-то вызывает MyPanelComponent.closePanel(), я мог бы позволить другому что-то еще, чтобы остановить закрытие панели?

Я имею в виду что-то вроде этого:

home.component.html:

<my-panel (closing)="panelIsClosing($event)"> ... </my-panel>

home.component.ts

panelIsClosing(event: any) {
  if (!allowPanelClose) {
    event.stopPropagation();
  }
}

Таким образом, ожидаемое поведение будет следующим:

  1. Что-то вызывает closePanel() в экземпляре <my-panel>.
  2. HomeComponent уведомляется, чтопанель пытается закрыть и при необходимости может отменить закрытие панели.
  3. Если ничего не отменяет, экземпляр <my-panel> продолжит закрытие.

Я не уверенс чего начать, но я думаю, что возможность использовать RxJS Observable s была бы идеальной.

РЕДАКТИРОВАТЬ: я знаю, что библиотека DevExtreme делает что-то вроде этого, я думаю, я нашел как они это реализуют но мне пока не удалось обернуть голову, и это, вероятно,больше, чем мне нужно ...

Ответы [ 2 ]

1 голос
/ 07 марта 2019

В вашем PanelComponent вы можете использовать тот факт, что поведение по умолчанию EventEmitter является синхронным *

  close() {
    this.closing.emit({
      preventClose: () => {
        this.closePrevented = true
      }
    });

    if (this.closePrevented) {
      return;
    }

    // Go on with closing implementation
  }

Очень простое / базовое демо здесь .

* Ссылка: EventEmitter docs

1 голос
/ 07 марта 2019

Самый простой вариант - разделить панель на два разных шага. Событие close и метод, который фактически закрывает его.

Это будет выглядеть примерно так:

import { Component, OnInit, EventEmitter, Output, Input } from '@angular/core';

@Component({
  selector: 'app-confirmable',
  templateUrl: './confirmable.component.html',
  styleUrls: ['./confirmable.component.css']
})
export class ConfirmableComponent implements OnInit {

  @Output()
  public close = new EventEmitter();

  @Input()
  public text: string;
  constructor() { }

  ngOnInit() {
  }

  public actualClose() {
    console.log('actual close logic');
  }
  public notifyClosure() {
    this.close.emit();
  }
}
<button (click)="notifyClosure()">{{text}}</button>

Тогда, где он использовался, вы можете решить, хотите ли вы на самом деле закрыть его или нет.

<app-confirmable text="I will never go away" (close)="doNotClose()"></app-confirmable>

<app-confirmable #confirmable text="I will never go away"(close)="confirmable.actualClose()"></app-confirmable>

Если вам нужна ссылка внутри контроллера, вы можете получить ее с помощью @ViewChild.

Здесь - минимальный рабочий пример.

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