I have used the component nested inside the same component. when I change the checkbox in the parent component attached function called correctly and Event emitter is working fine but when I change the child checkbox attached function was fired but event emitter not available (as of my knowledge ever matter is not bind with child one). I want to emit the data when I change the checkbox in the child.
If anyone know the answer please help me to solve this problem. And what is the terminology for using component nested inside the same component?
Thanking you
This is stackblitz link https://stackblitz.com/edit/angular-material-normal-tree (please check the console)
tree.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-tree',
templateUrl: './tree.component.html',
styleUrls: ['./tree.component.css'],
})
export class TreeComponent {
@Input() treeData: any;
@Output() toggleEmitter: EventEmitter<any> = new EventEmitter();
constructor() {}
toggleChild(node) {
console.log('from tree start');
console.log(node);
console.log('from tree end');
this.toggleEmitter.emit(node);
// if ('children' in node && node.children.length) {
// node.isExpand = !node.isExpand;
// }
}
test(node, i) {
node.parentIndex = i;
console.log(node);
// this.toggleEmitter.emit(node);
}
CBchangeEvent(node) {
console.log(node);
this.toggleEmitter.emit(node);
}
}
tree.component.html
<ul *ngIf="treeData">
<li *ngFor="let node of treeData;let i = index;">
<button mat-icon-button="" mattreenodetoggle="" class="mat-icon-button" (click)="toggleChild(node)">
<span class="mat-button-wrapper">
<mat-icon class="mat-icon material-icons" role="img" aria-hidden="true">
{{node.isExpand != 0 ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</span>
</button>
<mat-checkbox class="checklist-leaf-node" (change)="CBchangeEvent(node)">{{node.name}}</mat-checkbox>
<app-tree *ngIf="node.isExpand" [treeData]="node.children" (toggleEmitter)="test(node,i)"></app-tree>
</li>
</ul>
tree.component.css
ul {
list-style-type: none !important;
}
tree.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TreeComponent } from './tree.component';
import {
MatIconModule, MatCheckboxModule, MatFormFieldModule, MatButtonModule
} from '@angular/material';
@NgModule({
imports: [
CommonModule,
MatIconModule,
MatCheckboxModule,
MatFormFieldModule,
MatButtonModule
],
declarations: [TreeComponent],
exports: [TreeComponent]
})
export class TreeModule {
static forRoot() {
return {
ngModule: TreeModule
}
}
}
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
myData = [
{'id':1, 'name':'Main 1','isExpand':false,
'children':[
{'id':1, 'name':'Child 1', 'isExpand':false,
'children':[
{'id':2, 'name':'Test2','isExpand':false}
]
}
]
},
{
'id':2, 'name':'Main 2','isExpand':false
}
]
test(node) {
console.log('from app start');
console.log(node);
console.log('from app end');
if ('children' in node && node.children.length) {
node.isExpand = !node.isExpand;
}
}
}
app.component.html
<app-tree [treeData]='myData' (toggleEmitter)="test($event)"></app-tree>
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TreeModule } from './tree/tree.module';
import {
MdToolbarModule,
MdTabsModule,
MdButtonModule,
MdInputModule,
MdDatepickerModule,
MdNativeDateModule,
MdCheckboxModule,
MdRadioModule,
NoConflictStyleCompatibilityMode
} from '@angular/material';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule, BrowserAnimationsModule, MdToolbarModule, MdTabsModule, MdButtonModule, MdInputModule, MdDatepickerModule, MdNativeDateModule, MdCheckboxModule, MdRadioModule, TreeModule, NoConflictStyleCompatibilityMode ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }