Hi I'm newbie and I'm creating a project with a Reactive Form
; based on Recursive
Component that creates Dynamic Form
from JSON
file. The Sources
I Adapted the Recursive version procedures and other changes! My code is located in Stackblitz.
My component SelectsComponent
located in the selects.component.ts file, has the selector selector: 'selects',
I have:
@Output() addControl = new EventEmitter<JsonFormControls>();
and the method
public onSelectChange(event: MatSelectChange) {
console.log(this.form.value);
console.log('parent:' + this.parentControl || 'root');
this.control.value = event + '';
if (this.control.children) {
this.recursiveConcealer(this.control.children);
const child = this.control.children.find(
(child) => child.value === event + ''
);
this.newControl(child);
if (child.siblings) {
for (let sibling of child.siblings) {
this.newControl(sibling);
}
}
//Emit Event to Root
this.addControl.emit(child);
}
}
When the onSelectChange
method is called, then emit is performed this.addControl.emit(child);
In the template
selects.component.html file, I have this code:
<ng-container *ngFor="let child of control?.children">
<div fxFlex="100%">
<selects
*ngIf="child.type === 'select'"
[control]="child"
[parentControl]="control"
[formBuilder]="formBuilder"
></selects>
</div>
</ng-container>
I have the JsonFormComponent
located in the json-form.component.ts file, with this method:
public onAddControl(addControlEvent: JsonFormControls) {
this.addControl(addControlEvent);
addControlEvent.visible = true;
}
In it's template
json-form.component.html file, with this code:
<selects
*ngIf="control.type === 'select'"
[control]="control"
[visible]="true"
(addControl)="onAddControl($event)"
[formBuilder]="myFormBuilder"
></selects>
The problem raise when some Child-component (SelectsComponent
) is not a direct son of the Root Parent-Component (JsonFormComponent
), maybe is a grandson or depeer relation, as:
(level 0)JsonFormComponent
-> (level 1)SelectsComponent
-> (level 2)SelectsComponent
-> (level 3)SelectsComponent
How re-emit from SelectsComponent
child to SelectsComponent
parent.
QUESTIONS:
SelectsComponent
to (level 0)JsonFormComponent
?JsonFormComponent
to (level 3)SelectsComponent
?Thanks in advance!
I appreciate answer not based on services
that I know could be an alternative.
EDIT:
What is the Console.log(...)
expected?
console.log(`parent: ${this.parentControl?this.parentControl.name:'root'} -> control.name: ${this.control.name} -> Emitter: ${e?.name}` );
The first(or root) component is company
Something like:
parent: root -> control.name: company -> {Here the last node child}.
According to the click in the previous image
1st click (first level):
parent: root -> control.name: company -> Emitter: Petitioner (C2 -> P2).
2nd click (second level):
parent: root -> control.name: company -> Emitter: Service (C2 -> P2 -> S2).
Example: 3nd click (third level):
parent: root -> control.name: company -> Emitter: Request (C2 -> P2 -> S2 -> R2).
The console.log (or future operations) only will be performed in the context of the root (that is company
).
Here's the updated solution in https://stackblitz.com/edit/angular-ivy-6kccps
1.How to send or Emit Event from (level 3)SelectsComponent to (level 0)JsonFormComponent ?
Listen to the addControl event emitted by child selects
component in the selects.component.html
<selects
*ngIf="child.type === 'select'"
[control]="child"
[parentControl]="control"
[formBuilder]="formBuilder"
(addControl)="handleAddControl($event)"
></selects>
Emit the event
handleAddControl(data: any) {
this.addControl.emit(data);
}
This will send events from every instance of SelectsComponent
to be bubbled up to the top JsonFormComponent
2.How to send some Event of Acknowledgment from (level 0)JsonFormComponent to (level 3)SelectsComponent?
I am not really sure what is needed in terms of sending an acknowledge. However, I assume upon receiving an acknowledge in the original instance you would be performing some action, like updating some property. It can be achieved by adding a callback to the event payload as follows: selects.component.ts
//Emit Event to Root
public onSelectChange(event: MatSelectChange) {
...
...
...
const data = {child,
callback: () => {
console.log('Executing callback for control with label', this.control.name)
}
}
this.addControl.emit(data);
Execute the callback in json-form.component.ts
public onAddControl(addControlEvent: any) {
if (addControlEvent.callback) {
addControlEvent.callback();
}
this.addControl(addControlEvent);
addControlEvent.visible = true;
}