Skip to content

Commit 394805e

Browse files
author
maksym.koretskyi
committed
Task: implement custom change detection and renderer mechanism
1 parent db51016 commit 394805e

File tree

7 files changed

+8
-116
lines changed

7 files changed

+8
-116
lines changed

src/app/my-component.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,2 @@
1-
import { Component } from '../framework/decorators';
2-
3-
@Component({
4-
properties: ['name', 'age']
5-
})
61
export class MyComponent {
7-
name: string = 'Nick';
8-
age: number = 15;
92
}

src/framework/component.ts

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,5 @@ import { renderChanges } from './render-changes';
22
import { getRenderer } from './renderers';
33
import { PROPERTIES_SYMBOL } from './types';
44

5-
export function renderComponent<T>(C: any): T {
6-
const c = new C();
7-
8-
// save initial properties
9-
for (let i = 0; i < c[PROPERTIES_SYMBOL].length; i += 2) {
10-
c[PROPERTIES_SYMBOL][i + 1] = c[c[PROPERTIES_SYMBOL][i]];
11-
}
12-
13-
// set up interceptors that render changes
14-
for (let i = 0; i < c[PROPERTIES_SYMBOL].length; i += 2) {
15-
getRenderer().render(c[PROPERTIES_SYMBOL][i], c[PROPERTIES_SYMBOL][i + 1]);
16-
17-
Object.defineProperty(c, c[PROPERTIES_SYMBOL][i], {
18-
set(v) {
19-
this[PROPERTIES_SYMBOL][i + 1] = v;
20-
renderChanges(this);
21-
},
22-
get() {
23-
return this[PROPERTIES_SYMBOL][i + 1];
24-
},
25-
configurable: false
26-
});
27-
}
28-
29-
return c;
5+
export function renderComponent() {
306
}

src/framework/decorators.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,6 @@ import { ComponentDescriptor, PROPERTIES_SYMBOL } from './types';
22

33
export function Component(descriptor: ComponentDescriptor) {
44
return function (klass: any) {
5-
const p = klass.prototype;
65

7-
const properties = [];
8-
for (const p of descriptor.properties) {
9-
properties.push(p, undefined);
10-
}
11-
12-
Object.defineProperty(p, PROPERTIES_SYMBOL, {
13-
value: properties,
14-
configurable: false,
15-
writable: false
16-
});
17-
18-
return klass;
196
}
207
}

src/framework/render-changes.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,5 @@ import { getRenderer } from './renderers';
22
import { PROPERTIES_SYMBOL } from './types';
33

44
export function renderChanges(c: any) {
5-
const properties = c[PROPERTIES_SYMBOL];
6-
for (let i = 0; i < properties.length; i += 2) {
7-
getRenderer().render(properties[i], properties[i + 1])
8-
}
5+
96
}

src/framework/renderers.ts

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,15 @@
11
import { Renderer } from './types';
22

3-
export class ConsoleRenderer implements Renderer {
4-
container: Console = null;
5-
6-
init() {
7-
this.container = window.console;
8-
}
9-
10-
clear() {
11-
if (this.container === null) {
12-
this.init();
13-
}
14-
this.container.clear();
15-
}
16-
17-
render(p: string, v: any) {
18-
if (this.container === null) {
19-
this.init();
20-
}
21-
console.log(`${p}: ${v}`);
22-
}
3+
export class ConsoleRenderer {
234
}
245

25-
export class DOMRenderer implements Renderer {
26-
container: HTMLElement = null;
27-
28-
init() {
29-
this.container = document.createElement('div');
30-
this.container.classList.add('dom-renderer');
31-
document.body.appendChild(this.container);
32-
}
33-
34-
clear() {
35-
if (this.container === null) {
36-
this.init();
37-
}
38-
while (this.container.firstChild) {
39-
this.container.removeChild(this.container.firstChild);
40-
}
41-
}
42-
43-
render(p: string, v: any) {
44-
if (this.container === null) {
45-
this.init();
46-
}
47-
48-
const span = document.createElement('span');
49-
span.textContent = `${p}: ${v}`;
50-
this.container.appendChild(span);
51-
this.container.appendChild(document.createElement('br'));
52-
}
6+
export class DOMRenderer {
537
}
548

55-
export let renderer: Renderer = new ConsoleRenderer();
9+
export let renderer: Renderer;
5610

5711
export function setRenderer(type: string) {
5812
switch (type) {
59-
case 'dom': {
60-
renderer = new DOMRenderer();
61-
break;
62-
}
63-
case 'console': {
64-
renderer = new ConsoleRenderer();
65-
break;
66-
}
67-
default: {
68-
throw new Error('Unknown Renderer type');
69-
}
7013
}
7114
}
7215

src/framework/types.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
export interface ComponentDescriptor {
2-
properties: string[];
32
}
43

54
export interface Renderer {
6-
init(): void;
7-
8-
clear(): void;
9-
10-
render(property: string, value: any): void;
115
}
126

13-
export const PROPERTIES_SYMBOL = '__afProperties__';
7+
// export const PROPERTIES_SYMBOL;

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { MyComponent } from './app/my-component';
22
import { renderComponent } from './framework/component';
33
import { setRenderer } from './framework/renderers';
44

5+
/*
56
const c = renderComponent<MyComponent>(MyComponent);
67
78
// expect to see `name: Nick` and `age: 15` in the console
@@ -21,5 +22,6 @@ c.age = 18;
2122
2223
// expect to see `age: 38` in the console
2324
c.age = 38;
25+
*/
2426

2527

0 commit comments

Comments
 (0)