@syncfusion/ej2-angular-base 20.2.49 → 20.3.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,381 @@
1
+ /**
2
+ * Angular Component Base Module
3
+ */
4
+ import { getValue, isUndefined, setValue, isNullOrUndefined, attributes, createElement } from '@syncfusion/ej2-base';
5
+ import { EventEmitter, EmbeddedViewRef, Renderer2, ElementRef } from '@angular/core';
6
+ import { clearTemplate, registerEvents } from './util';
7
+
8
+ const SVG_REG: RegExp = /^svg|^path|^g/;
9
+
10
+ export interface IComponentBase {
11
+ registerEvents: (eventList: string[]) => void;
12
+ addTwoWay: (propList: string[]) => void;
13
+ }
14
+
15
+ interface Tag {
16
+ hasChanges: boolean;
17
+ getProperties?: Function;
18
+ isInitChanges: boolean;
19
+ hasNewChildren: boolean;
20
+ list: TagList[];
21
+ clearTemplate?: (arg: string[]) => void;
22
+ }
23
+
24
+ interface TagList {
25
+ getProperties: Function;
26
+ hasChanges: boolean;
27
+ isUpdated: boolean;
28
+ }
29
+
30
+ export class ComponentBase<T> {
31
+ public element: HTMLElement;
32
+ public tags: string[];
33
+ private ngAttr: string;
34
+ private srenderer: Renderer2;
35
+ protected isProtectedOnChange: boolean = true;
36
+ private isAngular: boolean;
37
+ private isFormInit: boolean = true;
38
+ public preventChange: boolean;
39
+ public isPreventChange: boolean;
40
+ protected oldProperties: { [key: string]: Object };
41
+ protected changedProperties: { [key: string]: Object };
42
+ protected finalUpdate: Function;
43
+ protected isUpdated: boolean;
44
+ public ngEle: ElementRef;
45
+
46
+ private tagObjects: { name: string, instance: Tag }[];
47
+ public onPropertyChanged: (newProp: Object, oldProp: Object) => void;
48
+ public appendTo: (ele: string | HTMLElement) => void;
49
+ public setProperties: (obj: Object, muteOnChange: boolean) => void;
50
+ public properties: Object;
51
+ public dataBind: Function;
52
+ private createElement: Function;
53
+ protected saveChanges(key: string, newValue: Object, oldValue: Object): void {
54
+ if (this.isProtectedOnChange) { return; }
55
+ this.oldProperties[key] = oldValue;
56
+ this.changedProperties[key] = newValue;
57
+ this.finalUpdate();
58
+ // tslint:disable-next-line:no-any
59
+ let changeTime: any = setTimeout(this.dataBind.bind(this));
60
+ let clearUpdate: Function = () => {
61
+ clearTimeout(changeTime);
62
+ };
63
+ this.finalUpdate = clearUpdate;
64
+ };
65
+
66
+ public destroy: Function;
67
+ private registeredTemplate: { [key: string]: EmbeddedViewRef<Object>[] };
68
+ private complexTemplate: string[];
69
+
70
+ private ngBoundedEvents: { [key: string]: Map<object, object> };
71
+ // tslint:disable-next-line:no-any
72
+ public ngOnInit(isTempRef?: any): void {
73
+ // tslint:disable-next-line:no-any
74
+ let tempOnThis: any = isTempRef || this;
75
+ tempOnThis.registeredTemplate = {};
76
+ tempOnThis.ngBoundedEvents = {};
77
+ tempOnThis.isAngular = true;
78
+ tempOnThis.isFormInit = true;
79
+ /* istanbul ignore next */
80
+ if (isTempRef) {
81
+ this.tags = isTempRef.tags;
82
+ }
83
+ tempOnThis.tags = this.tags || [];
84
+ tempOnThis.complexTemplate = this.complexTemplate || [];
85
+ tempOnThis.tagObjects = [];
86
+ tempOnThis.ngAttr = this.getAngularAttr(tempOnThis.element);
87
+ /* istanbul ignore next */
88
+ tempOnThis.createElement = (tagName: string, prop?:
89
+ { id?: string, className?: string, innerHTML?: string, styles?: string, attrs?: { [key: string]: string } }) => {
90
+ //tslint:disable-next-line
91
+ let ele: Element = tempOnThis.srenderer ? tempOnThis.srenderer.createElement(tagName) : createElement(tagName);
92
+ if (typeof (prop) === 'undefined') {
93
+ return <HTMLElement>ele;
94
+ }
95
+ ele.innerHTML = (prop.innerHTML ? prop.innerHTML : '');
96
+
97
+ if (prop.className !== undefined) {
98
+ ele.className = prop.className;
99
+ }
100
+ if (prop.id !== undefined) {
101
+ ele.id = prop.id;
102
+ }
103
+ if (prop.styles !== undefined) {
104
+ ele.setAttribute('style', prop.styles);
105
+ }
106
+ if (tempOnThis.ngAttr !== undefined) {
107
+ ele.setAttribute(tempOnThis.ngAttr, '');
108
+ }
109
+ if (prop.attrs !== undefined) {
110
+ attributes(ele, prop.attrs);
111
+ }
112
+ return <HTMLElement>ele;
113
+ };
114
+ for (let tag of tempOnThis.tags) {
115
+ let tagObject: { name: string, instance: Tag } = {
116
+ instance: getValue('child' + tag.substring(0, 1).toUpperCase() + tag.substring(1), tempOnThis),
117
+ name: tag
118
+ };
119
+ tempOnThis.tagObjects.push(tagObject);
120
+ }
121
+
122
+ let complexTemplates: string[] = Object.keys(tempOnThis);
123
+ for (let i = 0; i < complexTemplates.length; i++) {
124
+ var compProp = getValue(complexTemplates[i], tempOnThis);
125
+ if (typeof compProp === 'object' && compProp && compProp.elementRef) {
126
+ if (typeof compProp === 'object' && compProp && compProp.elementRef && complexTemplates[i].indexOf('_') !== -1 && complexTemplates[i].indexOf('Ref') === -1) {
127
+ setValue(complexTemplates[i] + 'Ref', compProp, tempOnThis);
128
+ }
129
+ if (tempOnThis.viewContainerRef && !getValue("_viewContainerRef", compProp.elementRef.nativeElement) && !getValue("propName", compProp.elementRef.nativeElement)) {
130
+ setValue("_viewContainerRef", tempOnThis.viewContainerRef, compProp.elementRef.nativeElement);
131
+ setValue("propName", complexTemplates[i].replace("Ref", ''), compProp.elementRef.nativeElement);
132
+ }
133
+ }
134
+ }
135
+ complexTemplates = Object.keys(tempOnThis);
136
+ complexTemplates = complexTemplates.filter((val: string): boolean => {
137
+ return /Ref$/i.test(val) && /\_/i.test(val);
138
+ });
139
+ for (let tempName of complexTemplates) {
140
+ let propName: string = tempName.replace('Ref', '');
141
+ let val: Object = {};
142
+ setValue(propName.replace('_', '.'), getValue(propName, tempOnThis), val);
143
+ tempOnThis.setProperties(val, true);
144
+ }
145
+ }
146
+
147
+ public getAngularAttr(ele: Element): string {
148
+ let attributes: NamedNodeMap = ele.attributes;
149
+ let length: number = attributes.length;
150
+ let ngAr: string;
151
+ for (let i: number = 0; i < length; i++) {
152
+ /* istanbul ignore next */
153
+ if (/_ngcontent/g.test(attributes[i].name)) {
154
+ ngAr = attributes[i].name;
155
+ }
156
+ }
157
+ return ngAr;
158
+ };
159
+ // tslint:disable-next-line:no-any
160
+ public ngAfterViewInit(isTempRef?: any): void {
161
+ // tslint:disable-next-line:no-any
162
+ let tempAfterViewThis: any = isTempRef || this;
163
+ let regExp: RegExp = /ejs-tab|ejs-accordion/g;
164
+ /* istanbul ignore next */
165
+ if (regExp.test(tempAfterViewThis.ngEle.nativeElement.outerHTML)) {
166
+ tempAfterViewThis.ngEle.nativeElement.style.visibility = 'hidden';
167
+ }
168
+
169
+ /**
170
+ * Root level template properties are not getting rendered,
171
+ * Due to ngonchanges not get triggered.
172
+ * so that we have set template value for root level template properties,
173
+ * for example: refer below syntax
174
+ * ```html
175
+ * <ejs-grid>
176
+ * <e-column></e-column>
177
+ * <ng-template #editSettingsTemplate></ng-template>
178
+ * </ejs-grid>
179
+ * ```
180
+ */
181
+ let templateProperties: string[] = Object.keys(tempAfterViewThis);
182
+ templateProperties = templateProperties.filter((val: string): boolean => {
183
+ return /Ref$/i.test(val);
184
+ });
185
+ for (let tempName of templateProperties) {
186
+ let propName: string = tempName.replace('Ref', '');
187
+ setValue(propName.replace('_', '.'), getValue(propName + 'Ref', tempAfterViewThis), tempAfterViewThis);
188
+ }
189
+ // Used setTimeout for template binding
190
+ // Refer Link: https://github.com/angular/angular/issues/6005
191
+ setTimeout(() => {
192
+ /* istanbul ignore else */
193
+ if (typeof window !== 'undefined' && tempAfterViewThis.element || tempAfterViewThis.getModuleName().includes('btn')) {
194
+ tempAfterViewThis.appendTo(tempAfterViewThis.element);
195
+ tempAfterViewThis.ngEle.nativeElement.style.visibility = '';
196
+ }
197
+ });
198
+ }
199
+ // tslint:disable-next-line:no-any
200
+ public ngOnDestroy(isTempRef?: any): void {
201
+ // tslint:disable-next-line:no-any
202
+ let tempOnDestroyThis: any = isTempRef || this;
203
+ /* istanbul ignore else */
204
+ setTimeout(() => {
205
+ if (typeof window !== 'undefined' && (tempOnDestroyThis.element.classList.contains('e-control'))) {
206
+ tempOnDestroyThis.destroy();
207
+ tempOnDestroyThis.clearTemplate(null);
208
+ // removing bounded events and tagobjects from component after destroy
209
+ tempOnDestroyThis.ngBoundedEvents = {};
210
+ tempOnDestroyThis.tagObjects = {};
211
+ tempOnDestroyThis.ngEle = null;
212
+ }
213
+ });
214
+ }
215
+ //tslint:disable-next-line
216
+ public clearTemplate(templateNames?: string[], index?: any): void {
217
+ clearTemplate(this, templateNames, index);
218
+ };
219
+ // tslint:disable-next-line:no-any
220
+ public ngAfterContentChecked(isTempRef?: any): void {
221
+
222
+ // tslint:disable-next-line:no-any
223
+ let tempAfterContentThis: any = isTempRef || this;
224
+ for (let tagObject of tempAfterContentThis.tagObjects) {
225
+ if (!isUndefined(tagObject.instance) &&
226
+ (tagObject.instance.isInitChanges || tagObject.instance.hasChanges || tagObject.instance.hasNewChildren)) {
227
+ if (tagObject.instance.isInitChanges) {
228
+ let propObj: { [key: string]: Object } = {};
229
+ // For angular 9 compatibility
230
+ // Not able to get complex directive properties reference ni Onint hook
231
+ // So we have constructed property here and used
232
+ let complexDirProps;
233
+ let list = getValue('instance.list', tagObject);
234
+ if (list && list.length) {
235
+ complexDirProps = list[0].directivePropList;
236
+ }
237
+ let skip: any = true;
238
+ if ((tempAfterContentThis as any).getModuleName && (tempAfterContentThis as any).getModuleName() === 'gantt') {
239
+ skip = false
240
+ }
241
+ if (complexDirProps && skip && complexDirProps.indexOf(tagObject.instance.propertyName) === -1) {
242
+ let compDirPropList = Object.keys(tagObject.instance.list[0].propCollection);
243
+ for (let h = 0; h < tagObject.instance.list.length; h++) {
244
+ tagObject.instance.list[h].propCollection[tagObject.instance.propertyName] = [];
245
+ let obj: any = {};
246
+ for (let k = 0; k < compDirPropList.length; k++) {
247
+ let complexPropName = compDirPropList[k];
248
+ obj[complexPropName] = tagObject.instance.list[h].propCollection[complexPropName];
249
+ }
250
+ for (let i = 0; i < tagObject.instance.list[h].tags.length; i++) {
251
+ let tag = tagObject.instance.list[h].tags[i];
252
+ let childObj = getValue('child' + tag.substring(0, 1).toUpperCase() + tag.substring(1), tagObject.instance.list[h]);
253
+ if (childObj) {
254
+ let innerchildObj = tagObject.instance.list[h]['child' + tag.substring(0, 1).toUpperCase() + tag.substring(1)];
255
+ if (innerchildObj) {
256
+ for (let j = 0; j < innerchildObj.list.length; j++) {
257
+ let innerTag = innerchildObj.list[0].tags[0];
258
+ if (innerTag) {
259
+ let innerchildTag = getValue('child' + innerTag.substring(0, 1).toUpperCase() + innerTag.substring(1), innerchildObj.list[j]);
260
+ if (innerchildTag) {
261
+ innerchildObj.list[j].tagObjects.push({ instance: innerchildTag, name: innerTag });
262
+ }
263
+ }
264
+ }
265
+ }
266
+ tagObject.instance.list[h].tagObjects.push({ instance: childObj, name: tag });
267
+ }
268
+ }
269
+ tagObject.instance.list[h].propCollection[tagObject.instance.propertyName].push(obj);
270
+ }
271
+ }
272
+ // End angular 9 compatibility
273
+ propObj[tagObject.name] = tagObject.instance.getProperties();
274
+ tempAfterContentThis.setProperties(propObj, tagObject.instance.isInitChanges);
275
+ } else {
276
+ /* istanbul ignore next */
277
+ if ((tempAfterContentThis[tagObject.name].length !== tagObject.instance.list.length) || (/diagram|tab|DashboardLayout/.test(tempAfterContentThis.getModuleName()))) {
278
+ tempAfterContentThis[tagObject.name] = tagObject.instance.list;
279
+ }
280
+ for (let list of tagObject.instance.list) {
281
+ let curIndex: number = tagObject.instance.list.indexOf(list);
282
+ let curChild: any = getValue(tagObject.name, tempAfterContentThis)[curIndex];
283
+ let complexTemplates: string[] = Object.keys(curChild);
284
+ complexTemplates = complexTemplates.filter((val: string): boolean => {
285
+ return /Ref$/i.test(val);
286
+ });
287
+ if (curChild.properties && Object.keys(curChild.properties).length !== 0){
288
+ for (let complexPropName of complexTemplates) {
289
+ complexPropName = complexPropName.replace(/Ref/, '');
290
+ curChild.properties[complexPropName] = !curChild.properties[complexPropName] ?
291
+ curChild.propCollection[complexPropName] : curChild.properties[complexPropName];
292
+ }
293
+ }
294
+ if (!isUndefined(curChild) && !isUndefined(curChild.setProperties)) {
295
+ if (/diagram|DashboardLayout/.test(tempAfterContentThis.getModuleName())) {
296
+ curChild.setProperties(list.getProperties(), true);
297
+ } else {
298
+ curChild.setProperties(list.getProperties());
299
+ }
300
+ }
301
+ list.isUpdated = true;
302
+ }
303
+ }
304
+ }
305
+ }
306
+ }
307
+
308
+ protected registerEvents(eventList: string[]): void {
309
+ registerEvents(eventList, this);
310
+ }
311
+
312
+ protected twoWaySetter(newVal: Object, prop: string): void {
313
+ let oldVal: Object = getValue(prop, this.properties);
314
+ if (oldVal === newVal) {
315
+ return;
316
+ }
317
+ this.saveChanges(prop, newVal, oldVal);
318
+ setValue(prop, (isNullOrUndefined(newVal) ? null : newVal), this.properties);
319
+ getValue(prop + 'Change', this).emit(newVal);
320
+ }
321
+
322
+ protected addTwoWay(propList: string[]): void {
323
+ for (let prop of propList) {
324
+ getValue(prop, this);
325
+ Object.defineProperty(this, prop, {
326
+ get: () => {
327
+ return getValue(prop, this.properties);
328
+ },
329
+ set: (newVal: Object) => this.twoWaySetter(newVal, prop)
330
+ });
331
+ setValue(prop + 'Change', new EventEmitter(), this);
332
+ }
333
+ }
334
+
335
+ public addEventListener(eventName: string, handler: Function): void {
336
+ let eventObj: EventEmitter<Object> = getValue(eventName, this);
337
+ if (!isUndefined(eventObj)) {
338
+ if (!this.ngBoundedEvents[eventName]) {
339
+ this.ngBoundedEvents[eventName] = new Map();
340
+ }
341
+ this.ngBoundedEvents[eventName].set(handler, eventObj.subscribe(handler));
342
+ }
343
+ }
344
+
345
+ public removeEventListener(eventName: string, handler: Function): void {
346
+ let eventObj: EventEmitter<Object> = getValue(eventName, this);
347
+ if (!isUndefined(eventObj)) {
348
+ (<EventEmitter<object>>this.ngBoundedEvents[eventName].get(handler)).unsubscribe();
349
+ }
350
+ }
351
+
352
+ public trigger(eventName: string, eventArgs: Object, success?: Function): void {
353
+
354
+ let eventObj: { next: Function } = getValue(eventName, this);
355
+
356
+ let prevDetection: boolean = this.isProtectedOnChange;
357
+ this.isProtectedOnChange = false;
358
+
359
+ if (eventArgs) {
360
+ (<{ name: string }>eventArgs).name = eventName;
361
+ }
362
+
363
+ if (!isUndefined(eventObj)) {
364
+ eventObj.next(eventArgs);
365
+ }
366
+ let localEventObj: Function = getValue('local' + eventName.charAt(0).toUpperCase() + eventName.slice(1), this);
367
+ if (!isUndefined(localEventObj)) {
368
+ localEventObj.call(this, eventArgs);
369
+ }
370
+
371
+ this.isProtectedOnChange = prevDetection;
372
+ /* istanbul ignore else */
373
+ if (success) {
374
+ this.preventChange = this.isPreventChange;
375
+ success.call(this, eventArgs);
376
+ }
377
+ this.isPreventChange = false;
378
+
379
+ }
380
+
381
+ }
@@ -0,0 +1,156 @@
1
+ import { EventEmitter, ElementRef } from '@angular/core';
2
+ import { getValue, setValue, isNullOrUndefined, isObject } from '@syncfusion/ej2-base';
3
+ import { ControlValueAccessor } from '@angular/forms';
4
+ /**
5
+ * Angular Form Base Module
6
+ */
7
+ export class FormBase<T> implements ControlValueAccessor {
8
+ public value: T;
9
+ public checked: boolean;
10
+ private skipFromEvent: boolean;
11
+ static readonly isFormBase = true;
12
+
13
+ public propagateChange(_: T): void { return; }
14
+ public propagateTouch(): void { return; }
15
+ public enabled: Object;
16
+ public disabled: Object;
17
+ public angularValue: T;
18
+ private isFormInit: Boolean;
19
+ public objCheck: Boolean;
20
+ public duplicateValue: string;
21
+ public duplicateAngularValue: string;
22
+
23
+ public element: HTMLElement;
24
+ public inputElement: HTMLInputElement;
25
+ private ngEle: ElementRef;
26
+ public appendTo: (ele: string | HTMLElement) => void;
27
+
28
+ public focus: EventEmitter<Object>;
29
+ public blur: EventEmitter<Object>;
30
+ public preventChange: boolean;
31
+ public isUpdated: boolean;
32
+ public oldValue: any;
33
+
34
+ public localChange(e: { value?: T, checked?: T }): void {
35
+ //tslint:disable-next-line
36
+ let value: T | any = (e.checked === undefined ? e.value : e.checked);
37
+ this.objCheck = isObject(value);
38
+ if (this.isUpdated === true) {
39
+ this.angularValue = this.oldValue;
40
+ }
41
+ if (this.objCheck === true) {
42
+ this.duplicateValue = JSON.stringify(value);
43
+ this.duplicateAngularValue = JSON.stringify(this.angularValue);
44
+ if (this.duplicateValue !== this.duplicateAngularValue && this.propagateChange !== undefined && value !== undefined) {
45
+ // Update angular from our control
46
+ this.propagateChange(value);
47
+ this.angularValue = value;
48
+ }
49
+ } else {
50
+ if (value !== this.angularValue && this.propagateChange !== undefined && value !== undefined) {
51
+ // While reset form using reset() method ng-dirty not get updated, so while value is empty just update angularValue only
52
+ if (value !== '' && value !== null) {
53
+ // Update angular from our control
54
+ this.propagateChange(value);
55
+ this.angularValue = value;
56
+ } else {
57
+ //tslint:disable-next-line
58
+ let optionalValue: any = value;
59
+ this.propagateChange(optionalValue);
60
+ this.angularValue = value;
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ public properties: Object;
67
+ public saveChanges: Function;
68
+
69
+
70
+ public registerOnChange(registerFunction: (_: T) => void): void {
71
+ this.propagateChange = registerFunction;
72
+ }
73
+
74
+ public registerOnTouched(registerFunction: () => void): void {
75
+ this.propagateTouch = registerFunction;
76
+ }
77
+ public twoWaySetter(newVal: Object, prop: string): void {
78
+ let oldVal: Object = this.oldValue || getValue(prop, this.properties);
79
+ let ele: HTMLElement = this.inputElement || this.element;
80
+ if (ele && oldVal === newVal && this.value === newVal &&
81
+ ((<HTMLInputElement>ele).value === undefined || (<HTMLInputElement>ele).value === '')) {
82
+ return;
83
+ }
84
+ this.saveChanges(prop, newVal, oldVal);
85
+ setValue(prop, (isNullOrUndefined(newVal) ? null : newVal), this.properties);
86
+ getValue(prop + 'Change', this).emit(newVal);
87
+ }
88
+ // tslint:disable-next-line:no-any
89
+ public ngAfterViewInit(isTempRef?: any): void {
90
+ // tslint:disable-next-line:no-any
91
+ let tempFormAfterViewThis: any = isTempRef || this;
92
+ // Used setTimeout for template binding
93
+ // Refer Link: https://github.com/angular/angular/issues/6005
94
+ // Removed setTimeout, Because we have called markForCheck() method in Angular Template Compiler
95
+ setTimeout(() => {
96
+ /* istanbul ignore else */
97
+ if (typeof window !== 'undefined') {
98
+ tempFormAfterViewThis.appendTo(tempFormAfterViewThis.element);
99
+ let ele: HTMLElement = tempFormAfterViewThis.inputElement || tempFormAfterViewThis.element;
100
+ ele.addEventListener('focus', tempFormAfterViewThis.ngOnFocus.bind(tempFormAfterViewThis));
101
+ ele.addEventListener('blur', tempFormAfterViewThis.ngOnBlur.bind(tempFormAfterViewThis));
102
+ }
103
+ this.isFormInit = false;
104
+ });
105
+ }
106
+ public setDisabledState(disabled: boolean): void {
107
+ this.enabled = !disabled;
108
+ this.disabled = disabled;
109
+ }
110
+
111
+ public writeValue(value: T): void {
112
+ let regExp: RegExp = /ejs-radiobutton/g;
113
+ //update control value from angular
114
+ if (this.checked === undefined) {
115
+ this.value = value;
116
+ } else {
117
+ // To resolve boolean type formControl value is not working for radio button control.
118
+ /* istanbul ignore next */
119
+ if (this.ngEle) {
120
+ if (typeof value === 'boolean') {
121
+ if (regExp.test(this.ngEle.nativeElement.outerHTML)) {
122
+ this.checked = value === this.value;
123
+ } else {
124
+ this.checked = value;
125
+ }
126
+ } else {
127
+ this.checked = value === this.value;
128
+ }
129
+ }
130
+ }
131
+ this.angularValue = value;
132
+ this.isUpdated = true;
133
+ // When binding Html textbox value to syncfusion textbox, change event triggered dynamically.
134
+ // To prevent change event, trigger change in component side based on `preventChange` value
135
+ this.preventChange = this.isFormInit ? false : true;
136
+ if (value === null) {
137
+ return;
138
+ }
139
+
140
+ }
141
+
142
+ public ngOnFocus(e: Event): void {
143
+ /* istanbul ignore else */
144
+ if (this.skipFromEvent !== true) {
145
+ this.focus.emit(e);
146
+ }
147
+ }
148
+
149
+ public ngOnBlur(e: Event): void {
150
+ this.propagateTouch();
151
+ /* istanbul ignore else */
152
+ if (this.skipFromEvent !== true) {
153
+ this.blur.emit(e);
154
+ }
155
+ }
156
+ }
@@ -0,0 +1,81 @@
1
+ import { ViewContainerRef, EmbeddedViewRef, ElementRef, TemplateRef } from '@angular/core';
2
+ import { setTemplateEngine, getTemplateEngine } from '@syncfusion/ej2-base';
3
+ import { setValue, getValue } from '@syncfusion/ej2-base';
4
+
5
+ let stringCompiler: (template: string, helper?: object) => (data: Object | JSON) => string = getTemplateEngine();
6
+
7
+ /**
8
+ * Angular Template Compiler
9
+ */
10
+ export function compile(templateEle: AngularElementType, helper?: Object):
11
+ //tslint:disable-next-line
12
+ (data: Object | JSON, component?: any, propName?: any) => Object {
13
+ if (typeof templateEle === 'string') {
14
+ return stringCompiler(templateEle, helper);
15
+ } else {
16
+ let contRef: ViewContainerRef = templateEle.elementRef.nativeElement._viewContainerRef;
17
+ let pName: string = templateEle.elementRef.nativeElement.propName;
18
+ //tslint:disable-next-line
19
+ return (data: Object, component?: any, propName?: any): Object => {
20
+ let context: Object = { $implicit: data };
21
+ /* istanbul ignore next */
22
+ let conRef: ViewContainerRef = contRef ? contRef : component.viewContainerRef;
23
+ let viewRef: EmbeddedViewRef<Object> = conRef.createEmbeddedView(templateEle as TemplateRef<Object>, context);
24
+ viewRef.detectChanges();
25
+ /* istanbul ignore next */
26
+ let viewCollection: { [key: string]: EmbeddedViewRef<Object>[] } = (component && component.registeredTemplate) ?
27
+ component.registeredTemplate : getValue('currentInstance.registeredTemplate', conRef);
28
+ propName = (propName && component.registeredTemplate) ? propName : pName;
29
+ if (typeof viewCollection[propName] === 'undefined') {
30
+ viewCollection[propName] = [];
31
+ }
32
+ viewCollection[propName].push(viewRef);
33
+ return viewRef.rootNodes;
34
+ };
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Property decorator for angular.
40
+ */
41
+ export function Template<T>(defaultValue?: Object): PropertyDecorator {
42
+ return (target: Object, key: string) => {
43
+ let propertyDescriptor: Object = {
44
+ set: setter(key),
45
+ get: getter(key, defaultValue),
46
+ enumerable: true,
47
+ configurable: true
48
+ };
49
+ Object.defineProperty(target, key, propertyDescriptor);
50
+ };
51
+ }
52
+
53
+ function setter(key: string): Function {
54
+ return function (val: AngularElementType): void {
55
+ if (val === undefined) { return; }
56
+ setValue(key + 'Ref', val, this);
57
+ if (typeof val !== 'string') {
58
+ val.elementRef.nativeElement._viewContainerRef = this.viewContainerRef;
59
+ val.elementRef.nativeElement.propName = key;
60
+ } else {
61
+ if (this.saveChanges) {
62
+ this.saveChanges(key, val, undefined);
63
+ this.dataBind();
64
+ }
65
+ }
66
+ };
67
+ }
68
+
69
+ function getter(key: string, defaultValue: Object): Function {
70
+ return function (): Object {
71
+ /* istanbul ignore next */
72
+ return getValue(key + 'Ref', this) || defaultValue;
73
+ };
74
+ }
75
+
76
+ export interface AngularElementType {
77
+ elementRef: ElementRef;
78
+ }
79
+
80
+ //tslint:disable-next-line
81
+ setTemplateEngine({ compile: (compile as any) });