I'm working on a simple stepper
but I'm stuck on how to handle an event within
ng-content. I've tried with a directive with no luck.
I'd like using appStepperNext and appStepperBack to
handle the click event to navigate within the different steps
I put it in the StepComponent but I'd like to handle it in
the StepperComponent
stepper
import { AfterContentInit, Component, ContentChildren, QueryList } from '@angular/core'; import { StepComponent } from './step/step.component'; @Component({ selector: 'app-stepper', template: ` <ul class="stepper"> <ng-container *ngFor="let step of steps; let i = index; let last = last"> <li (click)="selectStep(step)"> <button mat-mini-fab color="primary" [disabled]="!step.active"> {{ i + 1 }} </button> </li> <li class="line" *ngIf="!last"></li> </ng-container> </ul> <ng-content></ng-content> `, styleUrls: ['./stepper.component.scss'] }) export class StepperComponent implements AfterContentInit { @ContentChildren(StepComponent) steps: QueryList<StepComponent>; // contentChildren are set ngAfterContentInit() { // get all active steps const activeSteps = this.steps.filter(step => step.active); // if there is no active step set, activate the first if (activeSteps.length === 0) { this.selectStep(this.steps.first); } } selectStep(step: StepComponent) { // deactivate all steps this.steps.toArray().forEach(step => { step.active = false; }); // activate the step the user has clicked on. step.active = true; } } step
import { AfterContentInit, Component, ContentChildren, Input, QueryList } from '@angular/core'; import { StepperNextDirective } from './stepper-next.directive'; @Component({ selector: 'app-step', template: ` <div [hidden]="!active"> <ng-content></ng-content> </div> `, styleUrls: ['./step.component.scss'] }) export class StepComponent implements AfterContentInit { @Input() active = false; @ContentChildren(StepperNextDirective) dirs: QueryList<StepperNextDirective>; ngAfterContentInit() { console.log(this.dirs); } } Dir
import { Directive } from '@angular/core'; @Directive({ selector: '[stepperNext]' }) export class StepperNextDirective { constructor() { } } Usage
<app-stepper> <app-step> Step 1 Content <button appStepperNext>Next</button> </app-step> <app-step> Step 2 Content <button appStepperBack>Back</button> <button appStepperNext>Next</button> </app-step> <app-step> Step 3 Content <button appStepperNext>Back</button> <button mat-button>Submit</button> </app-step> </app-stepper> UPDATE after reply of @Bunyamin Coskuner
import { Directive, HostListener, Attribute } from '@angular/core'; import { IwdfStepperComponent } from './stepper.component'; @Directive({ selector: '[iwdfStepperNext]' }) export class StepperNextDirective { @HostListener('click') onClick() { this.stepper.next(this.current); } constructor( @Attribute('current') public current: number, private stepper: IwdfStepperComponent ) {} } Next
iwdfStepperNextbut in your html you haveappStepperNext. Could that be it?