Skip to content
This repository was archived by the owner on May 19, 2023. It is now read-only.

Commit 8b3962f

Browse files
committed
feat(component): automatically update to new added directives
1 parent 35a1679 commit 8b3962f

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/component.ts

+25-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import reactive from './core/reactive';
66
import render from './core/render';
77

88
import { setElementCustomProp } from './core/utils/elementCustomProp';
9+
import { DIRECTIVE_PREFIX } from './models/generics';
910

1011
export class Component {
1112
public state: State;
@@ -21,17 +22,18 @@ export class Component {
2122

2223
public mount(el: HTMLElement | string): State {
2324
// Accepts both selector and element reference
24-
const rootEl = typeof el === 'string' ? document.querySelector(el) : el;
25+
const rootEl =
26+
typeof el === 'string' ? document.querySelector<HTMLElement>(el)! : (el as HTMLElement);
2527
const $render = (deps: string[] = Object.keys(this.state)) => this.render(deps);
2628

27-
// AST generation
28-
this.ast = compile(rootEl as HTMLElement, this.state);
29+
this.ast = compile(rootEl, this.state);
2930
this.directives = { ...this.directives, ...directives };
3031
this.state = reactive({ ...this.state, $render }, this.render.bind(this), this.watchers);
3132

3233
this.render();
3334

34-
setElementCustomProp(rootEl as HTMLElement, 'component', this);
35+
setElementCustomProp(rootEl, 'component', this);
36+
this.handleMutations(rootEl);
3537

3638
return this.state;
3739
}
@@ -47,6 +49,25 @@ export class Component {
4749
public render(props: string[] = Object.keys(this.state)) {
4850
render(this.ast!, directives, this.state, props);
4951
}
52+
53+
public handleMutations(el: HTMLElement) {
54+
const mutationObserver = new MutationObserver((mutationsList) => {
55+
for (const mutation of mutationsList) {
56+
const attrName = String(mutation.attributeName);
57+
if (
58+
mutation.type === 'attributes' &&
59+
attrName.startsWith(DIRECTIVE_PREFIX) &&
60+
attrName !== `${DIRECTIVE_PREFIX}for`
61+
) {
62+
this.ast = compile(el, this.state);
63+
this.render();
64+
console.log('render');
65+
}
66+
}
67+
});
68+
69+
mutationObserver.observe(el, { attributes: true, subtree: true });
70+
}
5071
}
5172

5273
export const component = (state?: State) => new Component(state);

src/core/directives/for.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const forDirective = ({ el, data, state, node }: DirectiveProps) => {
1818

1919
const [expression, target] = data.value.split(/\s+(?:in|of)\s+/gim);
2020
const [item, index] = expression?.trim().replace(parenthesisWrapReplaceRE(), '').split(',');
21+
2122
const currArray =
2223
(state[target?.trim()] as unknown[]) ?? computeExpression(target?.trim(), el, true)(state);
2324
const ast = compile(el, state);
@@ -67,5 +68,5 @@ export const forDirective = ({ el, data, state, node }: DirectiveProps) => {
6768
el.removeAttribute(`${DIRECTIVE_PREFIX}for`);
6869
}
6970

70-
render(compile(el, state), directives, state, node.deps);
71+
render(compile(el, state, true), directives, state, node.deps);
7172
};

0 commit comments

Comments
 (0)