jquery - JavaScript-arkitektur - medlare, när ska man använda dem?


Detta är mer en allmän fråga om strukturen på min JavaScript-kod och om jag är på rätt väg mot välstrukturerad kod.

Den nuvarande koden jag har:

(function (myNamespace, $, undefined) {
    myNamespace.className = {
       init:function { } // do stuff
    }
} (window.myNamespace= window.myNamespace|| {}, jQuery)));

(function (myNamespace, $, undefined) {
        myNamespace.className2 = {
           init:function { } // do stuff
        }
} (window.myNamespace= window.myNamespace|| {}, jQuery)));

Uppenbarligen kan jag med ovanstående kod använda samma Namespace (enligt sida/avsnitt) och anropa dem via myNamespace.className.init() osv. Jag kan också kombinera dessa om jag vill, men jag kapslar in klasser för läsbarhet.

Nu har jag läst http://addyosmani.com/largescalejavascript/ om konceptet mediatörer. Min sekundära fråga är när (och om) jag borde använda dessa? Från className2 kan jag uppenbarligen göra:

 myNamespace.className2 = {
               init:function { myNamespace.className.init() } // do stuff
            }

Så varför skulle detta någonsin prenumerera på className som mediator.subscribe("classNameInit") och publicera det evenemanget i className?

Jag är mycket öppen för förslag om strukturen på min kod eftersom detta är något jag behöver få rätt medan jag ändrar sättet jag skriver min JavaScript på.

Svar #1

Du skulle använda det när du har flera delar som kommer att fungera tillsammans i obegränsade kombinationer där du inte känner till alla kombinationer i förväg eller där det är mer effektivt att anta alla kombinationer.

Låt oss säga att du byggde en social medieapp och skrev en klass för att kapsla in en lista med användare. På vissa skärmar öppnar klick på en användare i listan deras profil, på en annan skärm kanske klick på en användare söker efter varje kommentar de lämnat, och på en tredje skärm händer något annat.

Om du skulle skriva detta inte med mediator/pubsub, skulle du sluta med en massa if-satser i onclick-händelsen...

UserList.prototype.onUserClick = function(user) {
     // Check if we're supposed to open a popup
     if (this.mode === 'profile')

     // Check for something else
     else if (this.mode === 'something else')

     // Check for another case
     else if (this.mode === 'foo')
}

Mediator är en lösning på detta problem eftersom det inte kräver att UserList har kunskap om varje enskild situation den kan hamna i. Istället skulle koden ovan i UserList helt enkelt kunna förfinas för att sända ut ett meddelande när en användare klickas på...

UserList.prototype.onUserClick = function(user) {
    this.publish('user-click', user);
}

Då kan varje av dina andra skärmar eller UI-delar helt enkelt lyssna efter användarklick-meddelandet...

// On pages where there needs to be a popup profile
Mediator.onMessage('user-click', function(data) {
    showProfilePopup(data);
});

// Or perhaps on a search page
SearchBox.onMessage('user-click', function(data) {
    this.searchByUser(data);
});

Vidare, där medlaren börjar lysa är eftersom dessa andra UI-komponenter, som SearchBox, inte är intresserade av exakt när UserList avfyrar ett användarklick, de är bara intresserade när ett användarklick publiceras, andra UI-kontroller på sidan kan också avfyra användarklick och dessa delar kan reagera på det.

På en sidonotering, className={ } skapar inte en klass. Vad du förmodligen vill ha är className=function() { }.