Как закрыть / закрыть элемент Angular Snackbar изнутри элемента

В настоящее время у меня есть элемент snackbar с mat-progress-bar внутри него. Я хочу закрыть элемент snackbar. В настоящее время мой код выглядит так.

import { MAT_SNACK_BAR_DATA, MatSnackBar } from '@angular/material';
import { map } from 'rxjs/operators';

 @Component({
  selector: 'app-upload-progress-snackbar',
  template: `
  Progress:
  <mat-progress-bar mode = "determinate" [value] = "progress | async" *ngIf = "progress !== undefined"></mat-progress-bar>`,
  styles: [`mat-progress-bar { margin-top: 5px;}`],
})
export class UploadProgressComponent {
  constructor(@Inject(MAT_SNACK_BAR_DATA) public data) { }

  private started = false;
  public progress = this.data.uploadProgress.pipe(
    map(({ loaded, total }) => {
      if (loaded === undefined) {
        return !this.started ? 0 : 100;
      } else {
        this.started = true;
        return Math.round(loaded / (total || loaded) * 100);
      }
    },
  ));
}

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
9
0
17 994
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Для этого вы можете сделать следующее.

Этот snack-bar похож на mat-dialog .. вы должны вызвать dismiss() на MatSnackBarRef

DI renderer и MatSnackBarRef ... вам не нужен рендерер, если вы собираетесь уволить каким-то другим способом, это просто для демонстрационных целей.

 @Inject(MAT_SNACK_BAR_DATA) public data,
    private _snackRef: MatSnackBarRef<UploadProgressComponent>,
    private ren:Renderer2

Если вы хотите убрать при завершении индикатора выполнения, вы можете вызвать dismiss() в этой логике. Я закрою по щелчку.

Создайте прослушиватель событий щелчка в вашем constructor ...

{ 
  setTimeout(()=>{
    let snackEl = document.getElementsByClassName('mat-snack-bar-container').item(0);
    ren.listen(snackEl, 'click', ()=>this.dismiss())
  })

создайте свой dismiss()

  dismiss(){
    this._snackRef.dismiss();
  }

Stackblitz

https://stackblitz.com/edit/angular-mdyher?embed=1&file=app/snack-bar-component-example.ts

Решение Маршала хорошее, но требует больших усилий.

Следующее решение более чистое (нет необходимости передавать ссылку на закусочную или слушать какое-либо событие dom)

Stackblitz

Компонент Snackbar:

@Component({
  selector: 'app-upload-progress-snackbar',
  template: `
  Hello :)
  <button mat-button color = "primary" (click) = "dismiss()">Dismiss</button>  
  `,

})
export class UploadProgressComponent {
  constructor(
    @Inject(MAT_SNACK_BAR_DATA) public data) {}

  dismiss(){
    this.data.preClose(); //access preClose function when you want to close snackbar
  }
}

Код открытия закусочной:

openSnackBar() {
    const snackBar = this.snackBar.openFromComponent(UploadProgressComponent, {
      data: {preClose: () => {snackBar.dismiss()} } //pass a function to be called when you want to close the snackbar
    });
  }

Хороший способ сделать это - использовать внедрение зависимостей внутри настраиваемого компонента Snack Bar для создания ссылки на закусочную. Затем закройте компонент, используя эту ссылку.

CustomSnackBar.ts

constructor(
    private snackBarRef: MatSnackBarRef<GeneralSnackbarComponent>,
    @Inject(MAT_SNACK_BAR_DATA) public data: any
) { }

public dismiss(): void {
    this.snackBarRef.dismiss();
    event.preventDefault();
}

CustomSnackBar.html

<button id = "cancelBtn" mat-button (click) = "dismiss()">
    Cancel
</button>

Посмотрите этот Потрясающая демонстрация на Stackblitz.

export class PizzaPartyComponent {
  constructor(public snackBarRef: MatSnackBarRef<PizzaPartyComponent>,
  @Inject(MAT_SNACK_BAR_DATA) public data: any){}
}

Используйте snackBarRef.dismiss(), чтобы закрыть его.

Если вы столкнулись с мерцанием при отображении закусочной, запустите его в Ngzone.

constructor(private _snackBar: MatSnackBar, private zone: NgZone) {}

openSnackBar() {
  this.zone.run(()=>{
    this._snackBar.openFromComponent(PizzaPartyComponent, {
      data: this.message,
      duration: this.durationInSeconds * 1000,
    });  
  });
}

Может, эта статья могла бы помочь https://hoshcoding.com/courses/1/angular-material-snackbar.

Здесь вы можете увидеть полный пример закусочной из материала angular и то, как отменить действие.

Если вам нужен код, вот пример:

openSnackbar(message, action) {
    let snackBarRef = this.snackBar.open(message, action);
    snackBarRef.afterDismissed().subscribe(() => {
      console.info("The snackbar is dismissed");
    });
    snackBarRef.onAction().subscribe(() => {
      console.info("The snackbar action was triggered!");
    })
  }

С Уважением

Я думаю, что это хороший комментарий, но его недостаточно, чтобы дать мне -1 голос, потому что он работает отлично.

beanic 12.01.2021 15:26

Другие вопросы по теме