NodeJS 在前端使用vanilla JavaScript实现单例

at0kjp5o  于 2023-08-04  发布在  Node.js
关注(0)|答案(1)|浏览(144)

我有一个项目(vanilla web应用程序),我使用nodejs路由器从后端提供html文件:

router.get("/", (req, res) => {
    res.sendFile(views_dir + "index.html");
});

router.get("/login", (req, res) => {
    res.sendFile(views_dir + "login.html");
});

字符串
并将js文件作为静态app.use(express.static(path.join(__dirname, '/frontend')));提供,其中/frontend文件夹保存所有前端文件(包括html文件)。
现在,我有一个名为model.js的文件(在frontend文件夹中),我试图在其中实现一个singleton,它将保存所有页面通用的数据(例如用户当前是否登录):

const Model = (function () {
    let instance;

    function init() { 

        let isLogged = false;

        return {
            getIsLogged: function () {
                return isLogged;
            },
            setIsLogged: function (l) {
                isLogged = l;
            }
        }
    }
    return { 
        getInstance: function () {
            if (! instance) {
                instance = init();
            }
            return instance;
        }
    }
})();

但是当用户被重定向时,看起来像是model.js从后端重新导入,覆盖了上一页对模型的所有更改。(假设我们在用户登录时将模型中的isLogged变量更改为true,并重定向到'/',模型被刷新并覆盖)

有没有一种方法可以只用JavaScript来实现这样的需求?
我认为问题出在res.sendFile(views_dir + "index.html");上,它会将应用程序刷新到一个新的状态,而不会保存js文件的先前状态,有没有办法避免这种情况?只请求一次js文件?

tp5buhyn

tp5buhyn1#

感谢@Jared
我使用localStorage保存模型的当前状态,并在重定向到另一个页面时加载它。

const Model = (function () {

    let instance;

    let data = {
        isLogged: false,
    };

    function init_localStorage() {
        save_localStorage();
    }

    function load_localStorage() {
        let model = JSON.parse(localStorage.getItem('Model'));
        if (Object.keys(model).length === 0) {
            init_localStorage();
        }

        data = model;
    }

    function save_localStorage() {
        localStorage.setItem('Model', JSON.stringify(data));
    }

    function init() {
        load_localStorage();

        return {
            getIsLogged: function () {
                return data.isLogged;
            },
            setIsLogged: function (l) {
                data.isLogged = l;
            },

            saveData: function () {
                save_localStorage();
            }
        }
    }

    return {
        getInstance: function () {
            if (! instance) {
                instance = init();
            }
            return instance;
        }
    }
})();

字符串
最终,我有两个主要功能:save...load...,从localStorage对象读取\保存。正如Jared在评论中所说,JSON不能将函数字符串化,因此我创建了一个名为data的对象,在其中存储所有模型的数据(例如isLogged变量)。
现在,每当我想访问模型的数据时,我首先获取它的示例:let model = Model.getInstance();,然后我可以从返回的init函数中访问方法。当我请求Model示例时,它首先检查当前示例是否尚未初始化。如果没有,则调用load_localStorage,读取localStorage并将其保存到data变量。
在重定向到另一个页面之前,我调用Model示例的saveData将数据对象保存到localStorage,这样重定向到的页面就可以读取之前保存的状态。
在HTML文件中,我包含了这样的js文件:<script src="./../model/model.js"></script>
我相信有一个更好的解决方案,也许是一个更可读的代码,但这让我工作得很好:)

相关问题