2017-02-27 32 views
15

我一直在關注Modular Design Pattern很長一段時間,並且發現它非常有用,因爲它有助於良好維護代碼塊&將塊分離爲模塊。在Javascript中使用模塊化設計模式並使用DOM選擇

jQuery模塊結構的經常使用導致以下結構如下我的大多數應用程序/代碼:

(function() { 
    var chat = { 
     websocket: new WebSocket("ws://echo.websocket.org/"), 
     that: this, 
     init: function() { 
      this.scrollToBottom(); 
      this.bindEvents(); 
      this.webSocketHandlers(); 
     }, 
     bindEvents: function() { 
      this.toggleChat(); 
      this.filterPeople(); 
      this.compose(); 
     }, 
     elements: { 
      indicator: $(".indicator"), 
      statusText: $(".status-text"), 
      chatHeadNames: $(".people li .name"), 
      filterInput: $("#filter-input"), 
      msgInput: $("#msg-input"), 
      sendBtn: $(".send") 
     }, 
     ... 
     ... 
     ... 
     filterPeople: function() { 
      var that = this; 
      this.elements.chatHeadNames.each(function() { 
       $(this).attr('data-search-term', $(this).text().toLowerCase()); 
      }); 
     }, 
     ... 
     ... 
     }; 

     chat.init(); 
})(); 

我想知道的是,無論是通過jQuery引用我的所有元素的一部分單變量chat.elements良好做法

我的一個部分告訴我們,它確實是一次引用所有選擇器並將它們緩存在變量中的好方法,以便可以使用緩存變量來多次使用相同元素(而不是多個DOM選擇)。

我的另一部分告訴我這可能是一個反模式和特定的元素應該選擇和本地緩存在需要的時候。

我在整個過程中都使用過類似的結構,並且對代碼有不同的反應,但沒有什麼可靠的。任何幫助,將不勝感激。謝謝!

+0

使用元素來選擇名稱和狀態或其他東西不是好主意 如果有人用檢查元素更改名稱會怎麼樣? 或明天你的隊友改變主題一切都會被打破! –

+0

將數據保留在arry或object中並用於存儲使用localstorage –

+0

元素屬性在頁面加載時得到解析,並且事件直接綁定到節點,所以如果有人用inspect元素更改名稱,它不會導致問題。而'localstorage'對此是一個壞主意。 – nashcheez

回答

9

緩存選擇器是件好事。掛在他們身上是一個好主意。它通過反覆查詢DOM來提高性能。您上面的代碼看起來與BackboneJS和MarionetteJS代碼非常相似。

我有一些警告你,但:

  1. 這種模式可能會導致內存泄漏。考慮一下你失去了子視圖的情況,但是你保留了一些對它進行選擇的引用。這被稱爲懸掛指針。視圖不會真的消失。所有綁定將保留。事件將繼續在幕後進行。
  2. 您最終會遇到一個錯誤,您決定重新渲染屏幕的一部分。清理所有的綁定是必需的,你需要記住刪除和選擇器。如果你不這樣做,你幾乎肯定會遇到問題,你想知道爲什麼一個事件確實發射,但屏幕上沒有任何事情發生......(這將是因爲它發生在屏幕外,對你嘗試的元素刪除,那仍然存在... sorta)。
  3. 您正在查詢元素的當前方式會導致在整個頁面上進行搜索。看看https://api.jquery.com/find/。如果您緩存一個選擇器,然後在該選擇器內執行搜索,它可能會使您獲得一些性能提升。
+0

1.如果我通常不使用像骨幹這樣的框架,那麼沒有子視圖被銷燬,也沒有懸掛指針的情況。 2.事件除非被委託直接綁定到DOM節點,所以如果萬一我刪除了一個元素節點,綁定到的事件會自動分離。 3.我在緩存選擇器上使用'jQuery.find'來搜索子元素。 – nashcheez

+0

@nashcheez你不需要使用框架,你只需要建立自己的系統,負責清理(如果需要)。有很多應用程序不需要處理任何清理。無論如何,這些都不重要,它仍然是一個很好的模式。如果您確實需要清理,則可以更輕鬆地找到要清理的內容。 – Parris

+0

非常感謝您的回覆。我會就此做一點研究。 :) – nashcheez

0

我同意帕里斯,什麼緩存選擇器是好的。在我們的項目中,我們使用DI和模式Facade。這個結構有json配置,以防萬一新模塊成爲另一個結構。

我覺得你最:

  • 發送配置設置;
  • 緩存元件只有elems鍵;
  • 不緩存din3700元素params.classes;
  • 推遲助手的常用功能; 例如:

    (function() { 
    var chat = { 
        websocket: new WebSocket("ws://echo.websocket.org/"), 
        that: this, 
        params: { 
         elems: { 
          module: '.container', 
          indicator: ".indicator", 
          statusText: ".status-text", 
          chatHeadNames: ".people li .name", 
          filterInput: "#filter-input", 
          msgInput: "#msg-input", 
          sendBtn: ".send" 
         } 
         classes: { 
          dinamicInput: '.dinamicInput' 
         } 
        }, 
        init: function(params) { 
         opts = $.extend(true, $.extend(true, {}, that.params), params); 
         that.initElementsForModule(that.elements, that.params.elems); 
         this.scrollToBottom(); 
         this.bindEvents(); 
         this.webSocketHandlers(); 
        }, 
        bindEvents: function() { 
         this.toggleChat(); 
         this.filterPeople(); 
         this.compose(); 
        }, 
    
        initElementsForModule = function (elements, identifiers) { 
         var $module, 
          prop; 
    
         for (prop in identifiers) { 
          if (identifiers.hasOwnProperty(prop) && prop !== "module") { 
           elements["$" + prop] = $module.find(identifiers[prop]); 
          } 
         } 
    
        }, 
    
        elements: { 
         module: null, 
         indicator: null, 
         statusText: null, 
         chatHeadNames: null, 
         filterInput: null, 
         msgInput:null, 
         sendBtn: null 
        }, 
        ... 
        ... 
        ... 
        filterPeople: function() { 
         var that = this; 
         this.elements.chatHeadNames.each(function() { 
          $(this).attr('data-search-term', $(this).text().toLowerCase()); 
         }); 
        }, 
        ... 
        ... 
        }; 
    
        chat.init(); 
    })(); 
    
1
  • 我認爲,如果聊天模塊只有一個用於其子選擇器,那麼它是一個很好的模式。像:
<div id="chat-module"> 
    <div class="indicator">...</div> 
    <div class="status-text">...<div> 
    ... 
</div> 
<script src="and your chat module.js"></script> 
// your chat module selecting .indicator: 
// $('#chat-module.indicator') 
  • 此外,添加一個關機功能,以您的模塊。因此,當您從視圖中移除它時(與單頁應用一樣),可以取消選擇器並分離事件處理程序,如:delete this.elements.indicator和事件分離代碼。

也有這一樣,當用戶鍵入的東西,你觸發一個事件,並捕捉該事件的模塊中的其他/更好的模式。分離UI和代碼。