Skip to content

Commit 2a83acf

Browse files
committed
replaced xml2js dependencies with isomorphic-xml2js and deprecated JSONUtils due to performance issues
1 parent 07bad51 commit 2a83acf

File tree

18 files changed

+114
-53
lines changed

18 files changed

+114
-53
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ngx-dynamic-components",
3-
"version": "0.2.2",
3+
"version": "0.2.3",
44
"description": "NGX Dynamic Components is a configuration based dynamic components library for Angular. That allows you to rapidly create dynamic forms or any other mobile-friendly web layouts.",
55
"author": "FalconSoft Ltd",
66
"repository": {

projects/bootstrap/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ngx-dynamic-components/bootstrap",
3-
"version": "0.2.1",
3+
"version": "0.2.3",
44
"private": false,
55
"description": "@ngx-dynamic-components/bootstrap is Angular 7+ library what contains a bootstrap interfaces to build a configuration driven web pages and workflows.",
66
"author": "FalconSoft Ltd <[email protected]>",
@@ -21,7 +21,7 @@
2121
"peerDependencies": {
2222
"@angular/common": "^10.0.8",
2323
"@angular/core": "^10.0.8",
24-
"@ngx-dynamic-components/core": ">=0.2.1",
24+
"@ngx-dynamic-components/core": ">=0.2.3",
2525
"bootstrap-scss": "^4.4.1",
2626
"ngx-bootstrap": "^6.0.0"
2727
}

projects/bootstrap/src/lib/components/select/select.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component } from '@angular/core';
2-
import { JSONUtils, BindingProperties, propDescription, PropertyCategories, OptionValue,
3-
UIModel, ComponentDescriptor, Categories, AttributesMap, XMLResult, BaseUIComponent, PropTypes } from '@ngx-dynamic-components/core';
2+
import { BindingProperties, propDescription, PropertyCategories, OptionValue,
3+
UIModel, ComponentDescriptor, Categories, AttributesMap, XMLResult, BaseUIComponent, PropTypes, queryValue } from '@ngx-dynamic-components/core';
44
import { packageName } from '../../constants';
55
import example from './select.examples';
66

@@ -58,7 +58,7 @@ export class SelectComponent extends BaseUIComponent<SelectProperties> {
5858
}
5959

6060
if (typeof src === 'string' && src.startsWith('$.')) {
61-
return JSONUtils.find(this.dataModel, src);
61+
return queryValue(this.dataModel, src);
6262
}
6363
}
6464
}

projects/bootstrap/src/lib/components/select/select.examples.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export const example3: ComponentExample<UIModel<SelectProperties>> = {
5050
`,
5151
dataModel: {},
5252
scripts: `
53+
# Evaluated with JSPython https://jspython.dev/
54+
5355
def countryChanged():
5456
dataModel.city = null
5557
if dataModel.country == null:

projects/core/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ngx-dynamic-components/core",
3-
"version": "0.2.1",
3+
"version": "0.2.3",
44
"private": false,
55
"description": "@ngx-dynamic-components/core is Angular 7+ library what contains a core interfaces to build a configuration driven web pages and workflows.",
66
"author": "FalconSoft Ltd <[email protected]>",
@@ -20,6 +20,7 @@
2020
],
2121

2222
"peerDependencies": {
23+
"isomorphic-xml2js": "0.1.3",
2324
"@angular/cdk": "^10.1.2",
2425
"@angular/common": "^10.0.8",
2526
"@angular/core": "^10.0.8"

projects/core/src/lib/components/base-ui-component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { OnDestroy, HostBinding, SimpleChanges, OnChanges, Directive, Input, Output, EventEmitter } from '@angular/core';
22
import { AttributesMap, UIModel, ComponentEvent } from '../models';
33
import { JSONUtils } from '../utils/json.utils';
4-
import { kebabStrToCamel } from '../utils';
4+
import { kebabStrToCamel, queryValue, setValue } from '../utils';
55
import { StyleProperties, DataModelProperties, StylePropertiesList, BaseProperties } from '../properties';
66
import { InputProperties } from '../ui-components/input/input.component';
77
import { BaseDynamicComponent } from './base-dynamic-component';
@@ -67,7 +67,7 @@ export class BaseUIComponent<T = StyleProperties> extends BaseDynamicComponent<T
6767
const path = (this.properties as DataModelProperties).binding;
6868
// TODO: Handle case for Array type.
6969
if (!Array.isArray(this.dataModel)) {
70-
return JSONUtils.find(this.dataModel, path);
70+
return queryValue(this.dataModel, path);
7171
}
7272
}
7373

@@ -79,7 +79,7 @@ export class BaseUIComponent<T = StyleProperties> extends BaseDynamicComponent<T
7979
set componentDataModel(val) {
8080
if (this.properties.hasOwnProperty('binding')) {
8181
const path = (this.properties as DataModelProperties).binding;
82-
JSONUtils.setValue(this.dataModel, path, val);
82+
setValue(this.dataModel, path, val);
8383
}
8484
}
8585

projects/core/src/lib/html-elements/a/a.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Router } from '@angular/router';
33
import { StyleProperties, propDescription, PropTypes } from '../../properties';
44
import { ComponentExample, UIModel, ComponentDescriptor, Categories, XMLResult } from '../../models';
55
import { BaseHTMLElement, parseHTMLUIModel } from '../../components/base-html-element';
6-
import { JSONUtils } from '../../utils/json.utils';
6+
import { queryValue } from '../../utils';
77

88
@Directive()
99
export class AComponent extends BaseHTMLElement<LinkProperties> { // tslint:disable-line
@@ -40,7 +40,7 @@ export class AComponent extends BaseHTMLElement<LinkProperties> { // tslint:disa
4040
if (matches) {
4141
matches.forEach(m => {
4242
const path = m.replace(/[{}]+/, '');
43-
const res = JSONUtils.find(this.dataModel, path);
43+
const res = queryValue(this.dataModel, path);
4444
routerLink = routerLink.replace(m, res);
4545
});
4646
}

projects/core/src/lib/ui-components/radio-group/radio-group.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Component } from '@angular/core';
22
import { propDescription, BindingProperties, PropTypes } from '../../properties';
33
import { OptionValue, ComponentExample, UIModel, ComponentDescriptor, Categories, XMLResult, AttributesMap } from '../../models';
4-
import { JSONUtils } from '../../utils/json.utils';
54
import { BaseUIComponent } from '../../components/base-ui-component';
5+
import { queryValue } from '../../utils';
66

77
@Component({
88
selector: 'dc-radio-group',
@@ -35,7 +35,7 @@ export class RadioGroupComponent extends BaseUIComponent<RadioGroupProperties> {
3535
}
3636

3737
if (typeof src === 'string' && src.startsWith('$.')) {
38-
return JSONUtils.find(this.dataModel, src);
38+
return queryValue(this.dataModel, src);
3939
}
4040
}
4141
}

projects/core/src/lib/ui-components/select/select.component.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Component, HostListener, HostBinding, DoCheck } from '@angular/core';
22
import { BaseUIComponent } from '../../components/base-ui-component';
33
import { AttributesMap, OptionValue, ComponentExample, UIModel, ComponentDescriptor, Categories, XMLResult } from '../../models';
4-
import { JSONUtils } from '../../utils/json.utils';
54
import { BindingProperties, propDescription, PropertyCategories, PropTypes } from '../../properties';
5+
import { queryValue } from '../../utils';
66

77
@Component({
88
selector: 'select', // tslint:disable-line
@@ -53,7 +53,7 @@ export class SelectComponent extends BaseUIComponent<SelectProperties> implement
5353
}
5454

5555
if (typeof src === 'string' && src.startsWith('$.')) {
56-
list = JSONUtils.find(this.dataModel, src);
56+
list = queryValue(this.dataModel, src);
5757
}
5858

5959
if (list && (this.properties.labelProp || this.properties.valueProp)) {
@@ -133,15 +133,19 @@ export const example: ComponentExample<UIModel<SelectProperties>> = {
133133
`,
134134
dataModel: {},
135135
scripts: `
136+
# Evaluated with JSPython https://jspython.dev/
137+
136138
def countryChanged():
137139
dataModel.city = null
138-
print(dataModel.country)
139140
if dataModel.country == null:
140141
dataModel.cities = []
141142
if dataModel.country == "uk":
142143
dataModel.cities = [{label: "Select city", value: null}, {label: "London", value: "lon"}, {label: "Liverpool", value: "liv"}]
143144
if dataModel.country == "ua":
144145
dataModel.cities = [{label: "Select city", value: null}, {label: "Kyiv", value: "kyiv"}, {label: "Lviv", value: "lviv"}]
146+
147+
print(dataModel)
148+
145149
`,
146150
title: 'Basic select example'
147151
};

projects/core/src/lib/utils/index.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,50 @@ export type BaseHTMLElementConstructor = new () => BaseHTMLElement;
1414
* @param id Component identifier.
1515
*/
1616
export function getComponentById(uiModel: UIModel, id: string): BaseDynamicComponent {
17-
const componentUIModel = JSONUtils.find(uiModel, `$(children:id=${id})`) as UIModel;
17+
18+
function traverseUiModel(uModel: UIModel, predicate: (uModel) => boolean): UIModel {
19+
if (predicate(uModel)) {
20+
return uModel;
21+
}
22+
23+
if (uModel.children?.length) {
24+
for (const chileModel of uModel.children) {
25+
const res = traverseUiModel(chileModel, predicate);
26+
if (res) {
27+
return res;
28+
}
29+
}
30+
}
31+
32+
return null;
33+
}
34+
35+
const componentUIModel = traverseUiModel(uiModel, uim => uim.id === id);
1836
return componentUIModel?.getComponent();
1937
}
38+
39+
export function setValue(objectValue: object, path: string, value: any): void {
40+
JSONUtils.setValue(objectValue, path, value);
41+
}
42+
43+
export function queryValue(obj: any, path: string, defaultValue: any = null): any {
44+
if (path === '$' || path === '') {
45+
return defaultValue;
46+
}
47+
48+
if (path.startsWith('$.')) {
49+
path = path.substring(2);
50+
}
51+
52+
const props = path.indexOf('/') > 0 ? path.split('/') : path.split('.')
53+
54+
let res = obj;
55+
for (const p of props) {
56+
res = obj[p];
57+
if (!res && res !== 0) {
58+
return res || defaultValue;
59+
}
60+
}
61+
62+
return res;
63+
}

0 commit comments

Comments
 (0)