-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
100 lines (89 loc) · 2.56 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { createSignal, JSX, Setter } from "solid-js";
import { IAugmentedJQuery, IComponentOptions, IOnChangesObject } from "angular";
import { render } from "solid-js/web";
export type ComponentFn = (...args: any[]) => JSX.Element;
export function solid2angular(
dependencies: string[],
bindings: string[],
Component: ComponentFn,
): IComponentOptions {
return {
bindings: toNgBindings(bindings),
controller: [
"$element",
...dependencies,
class {
bindingSetters: Record<string, Setter<any>> = {};
injectedDeps: any[];
isRendered = false;
unrender: (() => void) | undefined;
constructor(
private $element: IAugmentedJQuery,
...injectedDeps: any[]
) {
this.injectedDeps = injectedDeps;
}
$onChanges(changes: IOnChangesObject) {
if (this.isRendered) {
this.updateProps(changes);
} else {
this.unrender = render(
() => Component(this.createProps(changes)),
this.$element[0],
);
this.isRendered = true;
}
}
$onDestroy() {
this.isRendered = false;
if (this.unrender) {
this.unrender();
}
}
createProps(changes: IOnChangesObject) {
const props: Record<string, any> = dependenciesToProps(
dependencies,
this.injectedDeps,
);
for (const changedProp of Object.keys(changes)) {
const [value, setValue] = createSignal(
changes[changedProp].currentValue,
);
Object.defineProperty(props, changedProp, {
get: () => value(),
});
this.bindingSetters[changedProp] = setValue;
}
return props;
}
updateProps(changes: IOnChangesObject) {
for (const changedProp of Object.keys(changes)) {
if (this.bindingSetters[changedProp]) {
this.bindingSetters[changedProp](
changes[changedProp].currentValue,
);
}
}
}
},
],
};
}
function toNgBindings(bindings: string[]) {
return bindings.reduce(
(acc, bindingName) => {
acc[bindingName] = "<";
return acc;
},
{} as Record<string, string>,
);
}
function dependenciesToProps(dependencies: string[], injectedDeps: any[]) {
return injectedDeps.reduce(
(acc, dep, i) => {
acc[dependencies[i]] = dep;
return acc;
},
{} as Record<string, any>,
);
}