Search code examples
angulartypescriptangular-material-stepper

How i can access components in a MatStep by typescript in angular


I need to access all components in stepper's step in typescript, i have the following:

<mat-vertical-stepper #stepper (selectionChange)="ChangeSelection($event)">
  <mat-step label="Step 1">
    Step 1
  </mat-step>
  <mat-step label="Step 2">
    Step 2
    <app-comp1>  </app-comp1>
    <app-comp2>  </app-comp1>
  </mat-step>
</mat-vertical-stepper>  

Knowing that comp1 and comp2 implements IComp (custom interface)

export interface IComp {
  MethodeFromInterface?: { (data?: any): void }; //this is optional
}

export class Comp1 implements IComp {
  MethodeFromInterface(data: any) {
    //do something here
  }
}

export class Comp2 implements IComp {
  MethodeFromInterface(data: any) {
    //do something here
  }
}

the main component has

ChangeSelection(event) {
  var m = (<IComp>event.selectedStep);
  if (m.MethodeFromInterface.InnerComponents[0]) // InnerComponents is an example  
    m.MethodeFromInterface("TEST");     
}

so is there is anything like innerComponents inside MatStep ?


Solution

  • Based on your comment, it sounds like you want to dynamically change the stepper content, based on the previous step. I would use an event-based approach for this, rather than a imperative approach.

    A solution could be to send events out of the step components into the parent component. Then let the parent render the appropriate changes.

    Parent HTML

    <mat-vertical-stepper #stepper (selectionChange)="ChangeSelection($event)">
      <mat-step label="Step 1">
        Step 1
        <app-comp0 (stateChanged)="step1State.next($event)">  </app-comp0>
      </mat-step>
      <mat-step label="Step 2">
        Step 2
        <app-comp1 [step1State]="step1State | async">  </app-comp1>
        <app-comp2 [step1State]="step1State | async">  </app-comp1>
      </mat-step>
    </mat-vertical-stepper>  
    

    Parent Typescript

    step1State = new EventEmitter();
    

    Child Typescript app-comp0

    @Output()
    stateChanged = new EventEmitter();
    

    Child Typescript app-comp1

    @Input()
    set step1State(newState) {
      // Do work here
    }
    

    Now Step 2 components depend on the state of the Step 1 component. You could continue this, linking different components based on many @Input's and @Output's of each component.

    This also makes it easier to reason about, as each component only depends on the events given, rather than a direct dependency.