suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Erstellen Sie ein Singleton-Muster in der Frontend-Entwicklung mit reinem JavaScript

<p>Übersetzen: Ich habe ein Projekt (reine Front-End-Webanwendung), in dem ich HTML-Dateien vom Backend mithilfe des Node.js-Routings bereitstelle: </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>Und stellen Sie JS-Dateien als statische Dateien bereit app.use(express.static(path.join(__dirname, '/frontend'))); wobei der Ordner /frontend alle Front-End-Dateien (einschließlich HTML-Dateien) enthält. <br /><br />Im Moment habe ich eine Datei namens model.js (im Frontend-Ordner) und versuche, ein Singleton-Muster zu implementieren, das von allen Seiten gemeinsam genutzte Daten enthält (z. B. ob der Benutzer aktuell angemeldet ist):</p><p><code></code><strong></strong></p> <pre class="brush:js;toolbar:false;">const Model = (function () { lass Beispiel; Funktion init() { let isLogged = false; zurückkehren { getIsLogged: function () { return isLogged; }, setIsLogged: Funktion (l) { isLogged = l; } } } zurückkehren { getInstance: function () { if (! Instanz) { Instanz = init(); } Rückgabeinstanz; } } })(); </pre> <p><strong>Aber wenn der Benutzer umgeleitet wird, scheint es, dass model.js erneut aus dem Backend importiert wird und alle Änderungen am Modell von der vorherigen Seite überschrieben werden. (Wenn sich der Benutzer beispielsweise anmeldet, ändern wir die Variable isLogged im Modell auf „true“ und leiten auf „/“ um. Das Modell wird aktualisiert und überschrieben.) <br /><br /> Möglichkeit, einfach zu verwenden: Implementiert JavaScript eine solche Anforderung? <br /><br />Ich denke, das Problem liegt bei res.sendFile(views_dir + "index.html");, es aktualisiert die Anwendung in einem neuen Zustand und speichert nicht die vorherige Version des JS Dateistatus, gibt es eine Möglichkeit, dies zu vermeiden? JS-Datei nur einmal anfordern? <br /></strong></p><p><code></code></p>
P粉986860950P粉986860950482 Tage vor520

Antworte allen(1)Ich werde antworten

  • 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>。

    我相信有更好的解决方案,也许有更易读的代码,但这个方法对我来说已经足够好用了 :)


    Antwort
    0
  • StornierenAntwort