2

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

2
  • The selector in your directive is iwdfStepperNext but in your html you have appStepperNext. Could that be it? Commented Mar 1, 2019 at 8:20
  • Thanks to spot it but it is a simple type. I dont really know how to manage the click button in the step component Commented Mar 1, 2019 at 8:25

1 Answer 1

1

I have created the same component for myself and achieved the exact thing you are trying to do.

Here is how you can do it.

You need to define some events within button directives and inject StepperComponent. Also, define a next method within StepperComponent.

Also, make sure you don't have a typo within your templates. I've changed selector to [appStepperNext]

@Directive({ selector: '[appStepperNext]' }) export class StepperNextDirective { constructor(private _stepper: StepperComponent) { } @HostListener('click') onClick() { this._stepper.next(); } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.