feat(framework): make component props reactive
This commit is contained in:
@@ -2600,9 +2600,43 @@ export const REACTIVE_RUNTIME = String.raw`
|
||||
});
|
||||
});
|
||||
|
||||
if (behavior) {
|
||||
installBehaviorFunctions(behavior.functions);
|
||||
var publicScopeApi = {
|
||||
// Prop expressions belong to the parent that mounted the component. The
|
||||
// server forwards these markers onto the rendered child root; evaluate
|
||||
// them here and write changes into the child's prop signals.
|
||||
Array.prototype.slice
|
||||
.call(el.querySelectorAll("[data-scope], [data-wrn-scope]"))
|
||||
.forEach(function (node) {
|
||||
if (!node.parentNode || ownerScope(node.parentNode) !== el) return;
|
||||
Array.prototype.slice.call(node.attributes).forEach(function (attr) {
|
||||
if (attr.name.indexOf("data-wrn-prop-bind-") !== 0) return;
|
||||
var binding;
|
||||
try { binding = JSON.parse(attr.value); } catch (_) { return; }
|
||||
if (!binding || binding.length !== 2) return;
|
||||
var propName = binding[0];
|
||||
var template = binding[1];
|
||||
reactive(function () {
|
||||
var exact = /^\{([^{}]+)\}$/.exec(template);
|
||||
var value;
|
||||
try {
|
||||
value = exact
|
||||
? evalExpr(exact[1].trim(), decodeLoopLocals(node))
|
||||
: template.replace(/\{([^{}]+)\}/g, function (_, expression) {
|
||||
var part = evalExpr(expression.trim(), decodeLoopLocals(node));
|
||||
return part == null ? "" : String(part);
|
||||
});
|
||||
} catch (_) { return; }
|
||||
var apply = function () {
|
||||
if (node.__wrnexusScopeApi) node.__wrnexusScopeApi.set(propName, value);
|
||||
};
|
||||
if (node.__wrnexusScopeApi) apply();
|
||||
else queueMicrotask(apply);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Every hydrated scope exposes state writes. Prop-only components need the
|
||||
// same API even when they have no behavior block.
|
||||
var publicScopeApi = {
|
||||
get: peekScope,
|
||||
set: writeScope,
|
||||
call: function (name) {
|
||||
@@ -2610,11 +2644,14 @@ export const REACTIVE_RUNTIME = String.raw`
|
||||
if (typeof fn !== "function") return undefined;
|
||||
return fn.apply(null, Array.prototype.slice.call(arguments, 1));
|
||||
},
|
||||
};
|
||||
el.__wrnexusScopeApi = publicScopeApi;
|
||||
el.querySelectorAll("[data-wrn-select]").forEach(function (select) {
|
||||
select.__wrnexusScopeApi = publicScopeApi;
|
||||
});
|
||||
};
|
||||
el.__wrnexusScopeApi = publicScopeApi;
|
||||
el.querySelectorAll("[data-wrn-select]").forEach(function (select) {
|
||||
select.__wrnexusScopeApi = publicScopeApi;
|
||||
});
|
||||
|
||||
if (behavior) {
|
||||
installBehaviorFunctions(behavior.functions);
|
||||
|
||||
(behavior.effects || []).forEach(function (source) {
|
||||
if (typeof source !== "string" || !source.trim()) return;
|
||||
|
||||
Reference in New Issue
Block a user