Reputation: 3700
I am working on functionality where I need to add component recursively and I want an event which will be triggered by the nested component at any level but it get handled on the Main parent component(appcomponent) which added that component
where is my recursively adding wts comp html
<div class="panel panel-default panel-body" *ngIf="rules">
<button class="btn btn-primary" (click)="addRule()">add rule</button>
<button class="btn btn-primary" (click)="addGroup()">add group</button>
<button class="btn btn-danger" (click)="removeGroup()" *ngIf="enableRemoveGroup">remove group</button>
<div *ngIf="rules.groups">
<!-- adding itself if there is group -->
<wts *ngFor="let group of rules.groups" [data]="group"></wts>
</div>
<rule *ngFor="let rule of rules.rules" [rule]="rule"></rule>
</div>
wts component .ts
@Component({
selector: 'wts',
templateUrl: './wts.component.html',
providers: [WtsServiceService],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class WTSComponent implements OnInit {
rules: Group;
enableRemoveGroup: boolean = false;
@Output() removeGroupCB = new EventEmitter();
@Input('data')
set data(value) {
if (value) {
this.enableRemoveGroup = true;
}
this.rules = value || new Group();
};
constructor(private wtsServiceService: WtsServiceService) {
this.rules = new Group();
}
private addGroup() {
if (!this.rules.groups) {
this.rules.groups = [];
}
this.rules.groups.push(new Group());
console.log(this.rules);
}
private removeGroup() {
delete this.rules;
}
private addRule() {
this.rules.rules.push(new Rule());
}
ngOnInit() { }
}
In my comp I have object rules which contain the rules and groups, and group contains rule and group
here is my model
export class Rule {
subjectType: string;
valueType: string;
subject: string;
value: string;
constructor(st = '', vt = '', s = '', v = '') {
this.subjectType = st;
this.valueType = vt;
this.subject = s;
this.value = v;
}
}
export class Group {
rules: Rule[];
groups: Group[];
constructor() {
this.rules = [];
this.rules.push(new Rule());
}
};
If we have group withing group then it nested itself to form the UI. and we have rule component to list rules
here is my rule comp .ts
@Component({
selector: 'rule',
templateUrl: './rule.component.html',
styleUrls: ['./rule.component.css'],
providers: [WtsServiceService],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RuleComponent implements OnInit {
rule: Rule;
@Input('rule')
set Setrule(value) {
this.rule = value;
}
constructor(private wtsServiceService: WtsServiceService) { }
private triggerHanlder() {
this.wtsServiceService.triggerCallBack();// to trigger appcomponent function
}
}
here is my rule comp .html
<p *ngIf="rule">
<button class="btn btn-danger" (click)="triggerHanlder()">trigger handler</button>
</p>
which will trigger an event when user select a valid rule and get handled by main component ie appcomponent
To do that I have created on service which returns observable which is subscribed on appcomponent and rule component call a function to trigger that event but its now working as expected.
here is my service
@Injectable()
export class WtsServiceService {
resultSubject: ReplaySubject<any> = new ReplaySubject(1);
constructor() { }
public handleCallBack() {
return this.resultSubject;
}
public triggerCallBack() {
this.resultSubject.next({});
}
}
here is my appcomponent
export class AppComponent {
constructor( private _wtsServiceService: WtsServiceService) {
}
ngOnInit() {
this._wtsServiceService.handleCallBack().subscribe(() => {
console.log('parent function');//this should get execute when user click on trigger handler on rule comp
})
}
}
appcomp > wts > wts > wts >...> rule (here I have to emit an event and should get handled on appcomp. this rule compo may at any level)
Please help to find the workaround and suggest if there is any other better approach.
Upvotes: 0
Views: 980
Reputation: 657168
I would make the root wts
component a different component root-wts
(can have the same template as the nested wts
component, provide a service that that is injected to every wts
and rule
and also root-wts
.
root-wts
subscribes to an observable in this service
wts
(if applicable) and rule
emit events using the observable in the shared service
Upvotes: 1