lesismal / pmjs

Help To Build Single-Page App And Make Native Fastest!
MIT License
13 stars 1 forks source link

Integration with Jeasyui #3

Closed centratelemedia closed 1 year ago

centratelemedia commented 1 year ago

Jeasyui have smart feature, by define class in div tag component automatic renderer, for example:

<table class="easyui-datagrid">
    <thead>
        <tr>
            <th data-options="field:'code'">Code</th>
            <th data-options="field:'name'">Name</th>
            <th data-options="field:'price'">Price</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>001</td><td>name1</td><td>2323</td>
        </tr>
        <tr>
            <td>002</td><td>name2</td><td>4612</td>
        </tr>
    </tbody>
</table>

but in pmjs above script doesnot automatic renderer to datagrid component, mybe pmjs can make this automatic renderer?

TIA

lesismal commented 1 year ago

pm.js is just a small tool to help create SPA. pm.js aims to gain high performance of vanila js, not designed to be a fully UI framework, because I'm just a newbie in frontend:joy:. You can easily use other UI frameworks like Jeasyui or bootstrap/jquery/angular together with pm.js.

Recently I'm trying to simplify the source code, then any other can easily modify the source code:

// Copyright 2020 lesismal. All rights reserved.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

let _evts = {}
function pub(event, data) {
    let eMap = _evts[event]
    for (let k in eMap) {
        let h = eMap[k]
        h && h.handler({ 'tag': h.tag, 'event': event, 'data': data })
    }
}

function sub(tag, event, handler) {
    let eMap = _evts[event]
    if (!eMap) {
        eMap = {}
        _evts[event] = eMap
    }
    eMap[tag] = { tag: tag, event: event, handler: handler }
}

function unsub(tag, event) {
    let eMap = _evts[event]
    if (!eMap) {
        return
    }
    if (eMap[tag]) {
        delete eMap[tag]
    }
}

function elem(id) {
    return document.getElementById(id)
}

function onload(f) {
    if (f && (typeof window !== "undefined")) {
        window.onload == f;
    }
}

function request(method, url, data, cb) {
    let resolve
    let p = new Promise(function (res) {
        resolve = res
        if (typeof (cb) == 'function') {
            resolve = function (ret) {
                res(ret)
                cb(ret)
            }
        }
        let r = new XMLHttpRequest()
        r.open(method, url, true)
        r.onreadystatechange = function () {
            if (r.readyState != 4) {
                return
            }
            if (r.status != 200) {
                resolve({ code: r.status, data: null, err: `request "${url}" failed with status code ${r.status}` })
                return
            }
            resolve({ code: r.status, data: r.responseText, err: null })
        }
        r.send(data)
    })
    return p
}

let _jsLoaded = {}
function loadJS(url, cb) {
    let id = _jsLoaded[url]
    if (id && elem(id)) {
        return
    }
    if (this.idCnt) {
        this.idCnt++
    } else {
        this.idCnt = 1
    }
    id = `$van_js_elem_` + this.idCnt
    let jsElem = document.createElement("script")
    jsElem.id = id
    jsElem.type = 'text/javascript'
    jsElem.src = url
    jsElem.async = true
    jsElem.onload = cb
    document.getElementsByTagName("body")[0].appendChild(jsElem)
    _jsLoaded[url] = jsElem.id
}

function loadHTML(id, url, cb) {
    let self = this
    return request("GET", url, null, function (res) {
        if (res.code == 200) {
            elem(id).innerHTML = res.data
        }
        (typeof (cb) == "function") && cb(res)
    })
}

function setRouter(router) {
    window.location.href = '#' + router;
}

function parseUrl() {
    let detail = location.hash.split("?")
    let path = detail[0].split("#")
    let router = path[1]
    let values = {}
    let params = detail[1] ? detail[1].split("&") : []
    for (let i = 0; i < params.length; i++) {
        let kv = params[i].split("=")
        values[kv[0]] = kv[1]
    }
    return {
        path: path[0],
        router: router,
        values: values
    }
}

let mainInited = false
class SPA {
    constructor(rootId, layers, isMain) {
        this.rootId = rootId
        this.layers = []
        this.routers = {}

        this.addLayers(layers)

        this.isMain = isMain
        if (isMain) {
            if (mainInited) {
                throw ("Only one main group can be created")
            }
            mainInited = true
            this.refresh()
        }
        this.select(null)
    }

    addLayer(layer) {
        this.addLayers(layer)
    }

    addLayers(layers) {
        if (!layers) return
        if (!(layers instanceof Array)) {
            layers = [layers]
        }

        for (let i = 0; i < layers.length; i++) {
            let layer = layers[i]
            if (!layer.id) {
                throw ("Invalid layers config: no id")
            }
            if (!layer.router) {
                throw ("Invalid layers config: no router and id")
            }
            this.routers[layer.router] = true
            this.layers.push(layer)
        }
    }

    addNode(node) {
        this.addLayer(layer)
    }

    addNodes(nodes) {
        this.addLayers(nodes)
    }

    select(router, isRefresh) {
        let layers = this.layers
        if (!router && !!layers && layers.length > 0) {
            router = layers[0].router
        }
        if (!this.routers[router]) {
            return
        }
        if (this.selected == router) {
            return
        }
        for (let i = 0; i < layers.length; i++) {
            let layer = layers[i]
            let id = layer.id
            if (layer.router != router) {
                if (layer.inited) {
                    elem(id) && (elem(id).style.display = 'none')
                    layer.onhide && layer.onhide()
                }
            } else {
                if (!elem(id)) {
                    let e = document.createElement("div")
                    e.id = id
                    elem(this.rootId).appendChild(e)
                }
                elem(id).style.display = 'block'
                if (!layer.inited) {
                    layer.inited = true
                    layer.oninit && layer.oninit(layer)
                    if (layer.source) {
                        if (!layer.loaded && !layer.loading) {
                            layer.loading = true
                            loadHTML(id, layer.source, function () {
                                layer.loading = false
                                if (layer.inited) {
                                    layer.loaded = true
                                    layer.onload && layer.onload(layer)
                                    layer.onshow && layer.onshow(layer)
                                } else {
                                    this.release(layer)
                                }
                            })
                        }
                    } else {
                        layer.onshow && layer.onshow(layer)
                    }
                } else {
                    !layer.loading && layer.onshow && layer.onshow(layer)
                }
            }
        }
        if (!isRefresh) {
            setRouter(router);
        }
        this.selected = router
    }

    refresh() {
        let self = this
        let fn = function () {
            let url = parseUrl()
            self.select(url.router, true)
        }
        if (!window["$van_refresh_inited"]) {
            window["$van_refresh_inited"] = true
            // window.addEventListener('load', fn)
            window.addEventListener('hashchange', fn)
        }
    }

    release(id) {
        if (!id) return
        let layers = this.layers
        for (let i = 0; i < layers.length; i++) {
            let layer = layers[i]
            if (id == layer.id) {
                elem(id).innerHTML = ""
                layer.inited = false
                layer.loaded = false
                return
            }
        }
    }
}

function newSPA(rootId, layers, isMain) {
    return new SPA(rootId, layers, isMain)
}

if ((typeof window !== "undefined") && !window["$van"]) {
    window["$van"] = {
        'pub': pub,
        'sub': sub,
        'unsub': unsub,
        'elem': elem,
        'onload': onload,
        'parseUrl': parseUrl,
        'request': request,
        'loadJS': loadJS,
        'loadHTML': loadHTML,
        'setRouter': setRouter,
        'newSPA': newSPA,
    }
}
lesismal commented 1 year ago

Well, I misunderstood in the previous reply. Would you please provide your full code that can reproduce this? including Jeasyui src or link

centratelemedia commented 1 year ago

@lesismal i just upload to https://github.com/centratelemedia/webgpsdemo.git

try it please

lesismal commented 1 year ago

I tried. It seems the style/css does not work when using jeasyui and pm.loadHTML(element.innerHTML="...") together. But it works fine when using bootstrap. I am not skilled with frontend, can't find the reason by now.

lesismal commented 1 year ago

Even if the elements seem all right, it doesn't work: image

so confused.

centratelemedia commented 1 year ago

@lesismal

i have found solution, jeasyui have function:

$.parser.parse();       // parse all the page
$.parser.parse('#cc');  // parse the specified node