Angular (v5 +) - Snackbar "openFromComponent", компонент связи - PullRequest
0 голосов
/ 18 мая 2018

Угловой (v5.2.10) Закусочная

- |Intro | - У меня есть один угловой компонент (назовем его «родительский»), инициализирующий угловой материал Snackbar, который называется snackBar.Передан SnackbarMessage, еще один компонент с шаблоном, содержащим разметку «снэк-бар».Использование snackBar.openFromComponent(SnackBarMessage) в этом случае необходимо, потому что мне нужно использовать больше, чем просто текст на панели «Снэкбар» (например, разметка, события щелчка и т. Д.), Где snackBar.open(message, action) недостаточно. - |Код | - Компонент «Родитель»:

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html'
})
export class Parent implements AfterViewInit {

  public constructor(public snackBar: MatSnackBar) { }

  public ngAfterViewInit(): void {
      this.snackBar.openFromComponent(SnackbarMessage);
  }

  public dismissSnackbar(): void {
    this.snackBar.dismiss();
  }
}

Компонент «SnackbarMessage»:

@Component({
  selector: 'app-snackbar-message',
  templateUrl: './snackbar-message.html'
})
export class SnackbarMessage { }

«snackbar-message.html»разметка:

<p>(Snackbar message)</p>
<button type="button" (click)="dismissSnackbar();">Dismiss</button>

- |Выпуск | - В импортированном шаблоне SnackbarMessage (snackbar-message.html) мне нужно вызвать родительский компонент dismissSnackbar();, как нам это сделать с текущей инкапсуляцией этого приложения Angular?

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Решение yatharth будет работать.

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

Создайте наблюдаемый поток и подпишитесь на него в своем компоненте снэк-бара.Он будет просто передавать логическое значение (истина или ложь), и вы можете переключать компонент закусочной с этим значением каждый раз, когда в потоке будет выдано новое значение.

Простой пример:

@Injectable()
export class SnackbarService {
    status: BehaviorSubject<boolean> = new BehaviorSubject(false);
    status$: Observable<boolean> = this.status.asObservable();
}

@Component({
    selector: 'app-snackbar-message',
    templateUrl: './snackbar-message.html'
})
export class SnackbarMessage { 
    open: boolean = false;

    constructor(public snackbarService: SnackbarService) {
        snackbarService.status$.subscribe((open: boolean) => this.open = open);
    }
}

Теперь в любом месте вашего приложения все, что вам нужно сделать, это открыть закусочную:

snackbarService.status.next(true);

Или это, чтобы закрыть закусочную:

snackbarService.status.next(false);

И есливы хотите получить больше случаев, чем просто открывать / закрывать, вы можете использовать перечисление с различными значениями:

export enum SnackbarStatus {
    Open,
    Closed,
    SomethingElse
}

Передать перечисление в вашем наблюдаемом потоке вместо логического:

@Injectable()
export class SnackbarService {
    status: BehaviorSubject<SnackbarStatus> = new BehaviorSubject(SnackbarStatus.Closed);
    status$: Observable<SnackbarStatus> = this.status.asObservable();
}
0 голосов
/ 18 ноября 2018

Сегодня я решил проблему, аналогичную вашей, используя MatSnackBar.openFromTemplate вместо MatSnackBar.openFromComponent.При таком подходе все функции дочернего компонента становятся напрямую доступными из родительского компонента.

Родительский компонент действует как класс-посредник между MatSnackBar и SnackBarMessageComponent.Теперь SnackBarMessageComponent отделяется от MatSnackBar и становится простым компонентом и может быть переименован в MessageComponent.Вы можете отправлять и получать данные между родительским и дочерним компонентами, используя обычные @Input и @Output.Вы можете добавить столько @Input s или @Output s, сколько хотите.

Код содержит более 1000 слов:

parent.component.html

<h1>parent component</h1>
<ng-template #snackBarTemplate>
    <app-message [msg]="message" (onDismissClick)="dismissSnackbar"></app-message>
</ng-template>

parent.component.ts

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html'
})
export class Parent implements AfterViewInit {

  @ViewChild('snackBarTemplate')
  snackBarTemplate: TemplateRef<any>;

  public message: string;

  public constructor(public snackBar: MatSnackBar) { }

  public ngAfterViewInit(): void {
     this.message = '(Snackbar message)';
     this.snackBar.openFromTemplate(snackBarTemplate);
  }

  public dismissSnackbar(): void {
     this.snackBar.dismiss();
  }
}

message.component.ts

@Component({
  selector: 'app-message',
  templateUrl: './message.html'
})
export class MessageComponent { 
    @Input()
    msg: string;

    @Output()
    onDismissClick= new EventEmitter<any>();

    dismissClicked() {
       this.onDismissClick.emit(null);
    }

}

message.component.html

<p>{{msg}}</p>
<button type="button" (click)="dismissClicked()">Dismiss</button>

(приведенный выше код не имеетбыл проверен)

0 голосов
/ 18 мая 2018

На самом деле вам не нужно вызывать метод dismissSnackbar () родительского компонента, чтобы отключить снэк-бар.Вы можете просто вставить MatSnackBar в компонент SnackbarMessage и вызвать метод dismiss () для этого внедренного экземпляра MatSnackBar.Как написано в docs , это скроет видимую в данный момент Snackbar, т. Е. Snackbar, открытый с использованием компонента «SnackbarMessage» в вашем примере.Ниже представлен обновленный компонент «SnackbarMessage»: -

Компонент «SnackbarMessage»:

@Component({
    selector: 'app-snackbar-message',
    templateUrl: './snackbar-message.html'
})
export class SnackbarMessage { 
    constructor(public snackBar: MatSnackBar) {}

    public dismissSnackbar(): void {
        this.snackBar.dismiss();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...