diff --git a/examples/jdom-template/main.js b/examples/jdom-template/main.js
index d213005..52097cf 100644
--- a/examples/jdom-template/main.js
+++ b/examples/jdom-template/main.js
@@ -1,4 +1,28 @@
-import { $, state, computed, html } from '../../index.js';
+import { $, $r, state, computed, html, JDOMComponent } from '../../index.js';
+
+class Test2 extends JDOMComponent {
+ test = state('Test2')
+
+ constructor() {
+ super()
+ }
+ render() {
+ console.log(this.test)
+ return html`a: ${this.test}`
+ }
+}
+$r('test-app', Test2)
+
+class Test {
+ image = state('Test1')
+ create(){
+ html`<${Test2} test=${this.image} /> `.appendTo(document.body);
+ }
+}
+
+new Test().create()
+
+
const tasks = state([]);
diff --git a/package.json b/package.json
index d365eeb..ba4845e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "jdomjs",
- "version": "3.1.11",
+ "version": "3.1.12",
"description": "A wrapper for query selector and html elements",
"main": "./index.js",
"types": "./types/index.d.ts",
diff --git a/src/Hook.js b/src/Hook.js
index cf01d78..8c8ab73 100644
--- a/src/Hook.js
+++ b/src/Hook.js
@@ -9,6 +9,10 @@ export default class Hook {
#destroyed = false
#alreadyProxied = false
+ static TRACKING = []
+ static IS_TRACKING = false
+
+
/**
* @param {T} value
*/
@@ -94,6 +98,7 @@ export default class Hook {
* @return {T}
*/
get value() {
+ Hook.track(this)
return this._value
}
@@ -104,8 +109,10 @@ export default class Hook {
dispatchListener(oldVal) {
for (let listener of this.listeners) {
- if (listener.call(this, this._value, oldVal) === true)
- break
+ try {
+ if (listener.call(this, this._value, oldVal) === true)
+ break
+ } catch (e) {}
}
}
@@ -128,4 +135,32 @@ export default class Hook {
toString() {
return `${this.value}`
}
+
+ /**
+ * @param {Hook} hook
+ */
+ static track(hook) {
+ if (Hook.IS_TRACKING) {
+ Hook.TRACKING.push(hook)
+ }
+ }
+
+ static enableTracking() {
+ Hook.IS_TRACKING = true
+ }
+ static disableTracking() {
+ Hook.IS_TRACKING = false
+ Hook.clearTracked()
+ }
+
+ /**
+ * @return {Hook[]}
+ */
+ static getTracked() {
+ return Hook.TRACKING
+ }
+
+ static clearTracked() {
+ Hook.TRACKING = []
+ }
}
\ No newline at end of file
diff --git a/src/decorators.ts b/src/decorators.ts
index 9982205..cf8d2a5 100644
--- a/src/decorators.ts
+++ b/src/decorators.ts
@@ -21,7 +21,7 @@ export function State() {
}
}
-export function Computed(dependencies: string[] | ((target: any) => Hook[])) {
+export function Computed(dependencies: string[] | ((target: any) => Hook[])) {
return function(target: any, key: string) {
const func = target[key];
diff --git a/src/hooks.js b/src/hooks.js
index 41d5427..00e32dc 100644
--- a/src/hooks.js
+++ b/src/hooks.js
@@ -10,18 +10,32 @@ export function state(initialValue) {
}
/**
+ * If dependencies is not given, the dependencies will be automatically seletected
+ *
* @template T
* @param {function(): T} callable
- * @param {Hook[]} dependencies
+ * @param {Hook[]|undefined} dependencies
* @return {Hook}
*/
-export function computed(callable, dependencies = []) {
+export function computed(callable, dependencies = undefined) {
const hook = new Hook(callable())
- for (let dependency of dependencies) {
- dependency.listeners.push(() => {
- hook.value = callable()
- })
+ if (dependencies === undefined) {
+ Hook.enableTracking()
+ callable()
+
+ for (const trackedElement of Hook.getTracked()) {
+ trackedElement.addListener(() => {
+ hook.value = callable()
+ })
+ }
+ Hook.disableTracking()
+ } else {
+ for (let dependency of dependencies) {
+ dependency.listeners.push(() => {
+ hook.value = callable()
+ })
+ }
}
return hook
diff --git a/src/template/TemplateDOMAdapter.js b/src/template/TemplateDOMAdapter.js
index 9bd41a4..5c4628f 100644
--- a/src/template/TemplateDOMAdapter.js
+++ b/src/template/TemplateDOMAdapter.js
@@ -144,8 +144,14 @@ export default class TemplateDOMAdapter {
if (usingJDOMComponent) {
if (key.endsWith('.attr')) {
elem.setAttribute(key.replace('.attr', ''), value)
+ } else if (key.endsWith('.unhook')) {
+ elem[key] = value
+ } else if (elem[key] instanceof Hook) {
+ elem[key].value = value
+ } else {
+ elem[key] = value
}
- elem[key] = value
+
return
}
elem.setAttribute(key, value)