Создание упрощенного angular материала аккордеона, но событие вывода не перехватывается - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь упростить материальный аккордеон angular, делая свою собственную версию, которая пытается немного упростить его. У меня есть шаговый компонент :

<mat-accordion>
    <ng-content>
    </ng-content>
</mat-accordion>

Это очень просто и имеет следующие методы:

import {
  Component,
  AfterViewInit,
  QueryList,
  ContentChildren,
  OnDestroy,
  Input
} from "@angular/core";
import { StepComponent } from "./step.component";
import { Subscription } from "rxjs";

@Component({
  selector: "app-stepper",
  templateUrl: "./stepper.component.html",
  styleUrls: ["./stepper.component.scss"]
})
export class StepperComponent implements AfterViewInit, OnDestroy {
  @Input() closeOthers: boolean = true;
  @ContentChildren(StepComponent) children: QueryList<any>;

  step = 0;
  private subscriptions: Subscription = new Subscription();

  constructor() {}

  ngAfterViewInit() {
    this.children.forEach((child: StepComponent, i: number) => {
      this.subscriptions.add(
        child.animate.subscribe(() => {
          this.setStep(i);
        })
      );
    });
  }

  ngOnDestroy() {
    this.subscriptions.unsubscribe();
  }

  setStep(index: number) {
    this.step = index;
    console.log(this.step);
  }

  nextStep() {
    this.step++;
    console.log(this.step);
  }

  prevStep() {
    this.step--;
    console.log(this.step);
  }
}

Обратите внимание на children подписки.

Затем я создал компонент шага

<mat-expansion-panel [expanded]="expanded"
    (click)="animateMe()">
    <mat-expansion-panel-header>
        <mat-panel-title>
            {{name}}
        </mat-panel-title>
    </mat-expansion-panel-header>
    <div>
        <ng-content>
        </ng-content>
    </div>
</mat-expansion-panel>

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

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

@Component({
  selector: "app-step",
  templateUrl: "./step.component.html",
  styleUrls: ["./step.component.scss"]
})
export class StepComponent implements OnInit {
  @Input() name: string;
  @Input() expanded: boolean;
  @Output() animate: EventEmitter<void> = new EventEmitter<void>();

  constructor() {}

  ngOnInit() {}

  animateMe() {
    console.log("clicked");
    this.animate.emit();
  }
}

Обратите внимание на событие Output. Итак, в моем компоненте у меня теперь есть это:

<app-stepper #stepper>
    <app-step name="Hall"
        *ngIf="hall"
        [expanded]="stepper.step === 0">


        <!-- emitted for brevity -->

        <button mat-raised-button
            type="button"
            color="primary"
            (click)="stepper.nextStep()">Next</button>
    </app-step>
    <app-step name="Video"
        [expanded]="stepper.step === 1">

        <!-- emitted for brevity -->

        </form>
    </app-step>
</app-stepper>

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

Кто-нибудь знает, почему мой код:

this.children.forEach((child: StepComponent, i: number) => {
  this.subscriptions.add(
    child.animate.subscribe(() => {
      this.setStep(i);
    })
  );
});

не попасться?

1 Ответ

1 голос
/ 13 февраля 2020

Я создал stackblitz , поскольку это показалось интересной проблемой.

Если я правильно понимаю проблему, я думаю, что на самом деле это # ​​простое исправление.

Я переместил событие click из mat-expansion-panel в компоненте step в mat-expansion-header.

<mat-expansion-panel [expanded]="expanded">
    <mat-expansion-panel-header (click)="animateMe()">
    </mat-expansion-panel-header>
</mat-expansion-panel>

Как вы сказали, подписка срабатывает, но затем обработчик кликов перезаписывал вызов nextStep, вызывающий его сброс.

Я полагаю, что неправильно понял проблему, основываясь на простоте этого?

...