Why does mat-slide-toggle not work when we use a custom directive to send it into the reusable generic component?

207 views Asked by At

Here is the link of POC on stackblitz.

In above POC I have app component as a root component, app-expansion-panel component as a reusable generic component and custom-expansion-panel directive as a custom directive. In app.component.html I used app-expansion-panel component and in that component I passed mat-slide-toggle using custom-expansion-panel directive. But somehow it is not working.

mat-slide-toggle should work properly.

1

There are 1 answers

0
Mr. Stash On BEST ANSWER

You are binding a method, and declaring the array inside that same method, so this is what is happening.

  • Every time change detection runs getFeaturesExpansionPanelData is called.
  • A new instance of featureExpansionPanelData is created when getFeaturesExpansionPanelData is called, this changes the value of panelData in AppExpansionPanelComponent after the view has been initialised, which is messing up the mat-sliders.

These are few easy solutions to the problem

  1. Declare featureExpansionPanelData in the constructor
constructor(){
  this.featureExpansionPanelData = [
    {
      label: 'Name',
      value: 'sample name',
      injected: false,
    },
    {
      label: 'Enabled',
      value: '',
      injected: true,
    },
  ];
}

getFeaturesExpansionPanelData() {
  return this.featureExpansionPanelData;
}
  1. Declare featureExpansionPanelData in the constructor and pass featureExpansionPanelData directly
constructor(){
  this.featureExpansionPanelData = [
    {
      label: 'Name',
      value: 'sample name',
      injected: false,
    },
    {
      label: 'Enabled',
      value: '',
      injected: true,
    },
  ];
}
<app-expansion-panel
  [panelDataInput]="featureExpansionPanelData"
  panelTitle="{{ name }}"
>
  1. Use an input setter and add a condition in there so that panelData value does not get changed
panelData: KeyValueAttributes[] = [];
@Input()
set panelDataInput(value) {
  if (this.panelData.length === 0) {
    this.panelData = value;
  }
}
<app-expansion-panel
  [panelDataInput]="getFeaturesExpansionPanelData()"
  panelTitle="{{ name }}"
>