Skip to content

Commit c472b07

Browse files
committed
fix(elements): Add handling for nesting of angula components in event args. Some optimizations.
1 parent 45b4637 commit c472b07

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

projects/igniteui-angular-elements/src/app/custom-strategy.ts

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
2828
/** Cached child instances per query prop. Used for dynamic components's child templates that normally persist in Angular runtime */
2929
protected cachedChildComponents: Map<string, ComponentRef<any>[]> = new Map();
3030
private setComponentRef: (value: ComponentRef<any>) => void;
31+
/** The maximum depth at which event arguments are processed and angular components wrapped with Proxies, that handle template set */
32+
private maxEventProxyDepth = 3;
3133

3234
/**
3335
* Resolvable component reference.
@@ -403,26 +405,39 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
403405
}
404406

405407
protected patchOutputComponents(eventArgs: any) {
406-
let componentConfig: ComponentConfig = this.findConfig(eventArgs);
407-
if (componentConfig?.templateProps) {
408-
// The event return directly reference to a component, so directly return a proxy of it.
409-
eventArgs = this.createElementsComponentProxy(eventArgs, componentConfig);
410-
} else if (!componentConfig) {
411-
// Check if the event args have property with component reference and replace it with proxy as well.
412-
for (const [key, value] of Object.entries(eventArgs)) {
413-
componentConfig = this.findConfig(value);
414-
if (componentConfig?.templateProps) {
415-
eventArgs[key] = this.createElementsComponentProxy(value, componentConfig);
416-
}
408+
return this.createProxyForComponentValue(eventArgs, 0);
409+
}
410+
411+
/**
412+
* Nested search of event args that contain angular components and replace them with proxies.
413+
* If event args are array of angular component instances should return array of proxies of each of those instances.
414+
* If event args are object that has a single property being angular component should return same object except the angular component being a proxy of itself.
415+
*/
416+
protected createProxyForComponentValue(value: any, depth: number) {
417+
if (depth > this.maxEventProxyDepth) {
418+
return value;
419+
}
420+
421+
if (value?.constructor?.name.startsWith("_Igx")) {
422+
const componentConfig = this.findConfig(value);
423+
if (componentConfig?.templateProps) {
424+
return this.createElementsComponentProxy(value, componentConfig);
425+
}
426+
} else if (Array.isArray(value)) {
427+
return value.map(item => this.createProxyForComponentValue(item, depth + 1))
428+
} else if (typeof value === "object" && Object.entries(value).length) {
429+
for (const [key, item] of Object.entries(value)) {
430+
value[key] = this.createProxyForComponentValue(item, depth + 1);
417431
}
418432
}
419-
return eventArgs;
433+
434+
return value;
420435
}
421436

422-
/** Find config for a component, assuming the provided object is correct. Otherwise will return undefined. */
423-
protected findConfig(component: any) {
437+
/** Find config for a argument, assuming the provided object is correct. Otherwise will return undefined. */
438+
protected findConfig(value: any) {
424439
// Make sure we match the correct type(first half) and not the one it inherits(second half of check).
425-
return this.config.find((info: ComponentConfig) => component instanceof info.component && !(component.__proto__ instanceof info.component));
440+
return this.config.find((info: ComponentConfig) => value instanceof info.component && !(Object.getPrototypeOf(value) instanceof info.component));
426441
}
427442

428443
/** Create proxy for a component that handles setting template props, making sure it provides correct TemplateRef and not Lit template */

0 commit comments

Comments
 (0)