Create a singleton pattern in front-end development using pure JavaScript
P粉986860950
P粉986860950 2023-08-03 12:09:44
0
1
557
<p>Translate: I have a project (pure front-end web application) where I serve HTML files from the backend using Node.js routing: </p> <pre class="brush:js;toolbar:false;">router.get("/", (req, res) => { res.sendFile(views_dir "index.html"); }); router.get("/login", (req, res) => { res.sendFile(views_dir "login.html"); }); </pre> <p>And serve JS files as static files app.use(express.static(path.join(__dirname, '/frontend'))); where the /frontend folder contains all front-end files (including HTML files). <br /><br />Right now, I have a file called model.js (in the frontend folder) and I'm trying to implement a singleton pattern that holds data shared by all pages ( For example, whether the user is currently logged in):</p><p><code></code><strong></strong></p> <pre class="brush:js;toolbar:false;">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; } } })(); </pre> <p><strong>But when the user is redirected, it seems that model.js is imported from the backend again, overwriting all changes to the model from the previous page. (For example, when the user logs in, we change the isLogged variable in the model to true and redirect to '/', the model will be refreshed and overwritten) <br /><br /> Is there a way to just use Does JavaScript implement such a requirement? <br /><br />I think the problem is with res.sendFile(views_dir "index.html");, it refreshes the application to a new state and does not save the previous state of the js file , is there any way to avoid this? Request js file only once? <br /></strong></p><p><code></code></p>
P粉986860950
P粉986860950

reply all(1)
P粉764785924

With the help of @Jared, I solved this problem.

I used localStorage to save the current state of the model and reload it when redirecting to another page.

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;
        }
    }
})();

Ultimately, I have two main functions: save... and load..., which read and save data from the localStorage object. As Jared said in the comments, JSON cannot stringify functions, so I created an object called data in which I store all the model's data (such as the isLogged variable).

Now, whenever I want to access the model's data, I first get its instance: let model = Model.getInstance(); Then I can access the method from the returned init function. When I request a Model instance, it first checks if the current instance is initialized. If not initialized, it calls the load_localStorage function to read data from localStorage and save it to the data variable.

Before redirecting to another page, I call the saveData function of the Model instance to save the data object to localStorage so that the redirected page can read the previously saved state.

In the HTML file, I included the js file like this: <script src="./../model/model.js"></script>.

I'm sure there are better solutions, maybe with more readable code, but this method works well enough for me :)


Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template