Optimize SUI frontend and backend script data sharing

This commit is contained in:
Max 2024-07-26 15:25:04 +08:00
parent 002f409e67
commit 602333bd02
3 changed files with 57 additions and 4 deletions

View file

@ -341,7 +341,10 @@ func (page *Page) parseProps(from *goquery.Selection, to *goquery.Selection, ext
exp := dataTokens.MatchString(attr.Val)
prop := PageProp{Key: attr.Key, Val: attr.Val, Trans: trans, Exp: exp}
page.props[attr.Key] = prop
to.SetAttr(attr.Key, attr.Val)
// Set the prop
key := fmt.Sprintf("prop:%s", attr.Key)
to.SetAttr(key, attr.Val)
}
if extra != nil && len(extra) > 0 {

View file

@ -42,7 +42,46 @@ const libsuisource = `
function __sui_props(elm) {
this.Get = function (key) {
return elm && elm.getAttribute(key);
if (!elm || typeof elm.getAttribute !== "function") {
return null;
}
const k = "prop:" + key;
const v = elm.getAttribute(k);
const json = elm.getAttribute("json-attr-prop:" + key) === "true";
if (json) {
try {
return JSON.parse(v);
} catch (e) {
return null;
}
}
return v;
}
this.List = function () {
const props = {};
if (!elm || typeof elm.getAttribute !== "function") {
return props;
}
const attrs = elm.attributes;
for (let i = 0; i < attrs.length; i++) {
const attr = attrs[i];
if (attr.name.startsWith("prop:")) {
const k = attr.name.replace("prop:", "");
const json = elm.getAttribute("json-attr-prop:" + k) === "true";
if (json) {
try {
props[k] = JSON.parse(attr.value);
} catch (e) {
props[k] = null;
}
continue;
}
props[k] = attr.value;
}
}
return props;
}
}
@ -123,6 +162,10 @@ const libsuisource = `
this.SetJSON = function (key, value) {
elm.setAttribute("json:" + key, JSON.stringify(value));
}
this.GetData = function () {
return this.GetJSON("__component_data") || {};
}
}
`
@ -184,6 +227,7 @@ const compEventScriptTmpl = `
const componentInitScriptTmpl = `
this.root = %s;
this.store = new __sui_store(this.root);
this.props = new __sui_props(this.root);
`
// Inject code

View file

@ -260,12 +260,13 @@ func (parser *TemplateParser) parseElementComponent(sel *goquery.Selection) {
com := sel.AttrOr("s:cn", "")
props := map[string]interface{}{}
for _, attr := range sel.Nodes[0].Attr {
if !strings.HasPrefix(attr.Key, "s:") && attr.Key != "parsed" {
if strings.HasPrefix(attr.Key, "prop:") {
var val any = attr.Val
var key = strings.TrimPrefix(attr.Key, "prop:")
if _, exist := sel.Attr("json-attr-" + attr.Key); exist {
val = ValueJSON(attr.Val)
}
props[attr.Key] = val
props[key] = val
}
}
@ -299,6 +300,11 @@ func (parser *TemplateParser) parseElementComponent(sel *goquery.Selection) {
compParser.data[k] = v
}
}
raw, err := jsoniter.MarshalToString(data)
if err != nil {
raw = fmt.Sprintf(`"%s"`, err.Error())
}
sel.SetAttr("json:__component_data", raw)
}
err = compParser.RenderSelection(sel)