首頁  >  問答  >  主體

在前端開發中使用純JavaScript建立一個單例模式

<p>Translate: 我有一個專案(純前端Web應用),我使用Node.js路由從後端提供HTML檔:</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>並將JS檔案作為靜態檔案進行服務 app.use(express.static(path.join(__dirname, '/frontend'))); 其中/frontend資料夾包含所有前端檔案(包括HTML檔案)。 <br /><br />現在,我有一個名為model.js的檔案(在frontend資料夾中),我正在嘗試實作單例模式,用於保存所有頁面共享的資料(例如使用者目前是否已登入):</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>但當使用者被重定向時,似乎model.js會再次從後端匯入,覆蓋前一個頁面對模型的所有變更。 (例如,當使用者登入時,我們將模型中的isLogged變數更改為true,並重定向到'/',模型將被刷新和覆蓋)<br /><br />是否有辦法只使用JavaScript實現這樣的需求? <br /><br />我認為問題出在res.sendFile(views_dir "index.html");上,它會將應用程式刷新到新的狀態,並且不保存js檔案的先前狀態,有沒有辦法避免這種情況?只請求一次js檔? <br /></strong></p><p><code></code></p>
P粉986860950P粉986860950444 天前498

全部回覆(1)我來回復

  • P粉764785924

    P粉7647859242023-08-04 00:36:22

    透過@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>。

    我相信有更好的解決方案,也許有更易讀的程式碼,但這個方法對我來說已經足夠好用了 :)


    回覆
    0
  • 取消回覆