2013-01-08 23 views
6

Mi manca ovviamente qualche concetto/comprensione e la maggior parte delle nozioni di base OO di javascript!Posso avere più istanze di un modulo RequireJS?

Mi piace usare RequireJS e la mia app Web ora sembra più un'app strutturata piuttosto che un intero mucchio di codice pazzo.

Sto solo cercando di capire come/se quanto segue è possibile.

Ho un modulo che agisce come modulo base Dataservice chiamato dataservice_base come segue:

define(['dataservices/dataservice'], function (dataservice) { 

    // Private:  Route URL 
    this.route = '/api/route-not-set/'; 
    var setRoute = function (setRoute) { 
     this.route = setRoute; 
     return; 
    } 

    // Private: Return route with/without id 
    var routeUrl = function (route, id) { 
     console.log('** Setting route to: ' + route); 
     return route + (id || "") 
    } 

    // Private: Returns all entities for given route 
    getAllEntities = function (callbacks) { 
     return dataservice.ajaxRequest('get', routeUrl()) 
     .done(callbacks.success) 
     .fail(callbacks.error) 
    }; 

    getEntitiesById = function (id, callbacks) { 
     return dataservice.ajaxRequest('get', routeUrl(this.route, id)) 
     .done(callbacks.success) 
     .fail(callbacks.error) 
    }; 

    putEntity = function (id, data, callbacks) { 
     return dataservice.ajaxRequest('put', routeUrl(this.route, id), data) 
     .done(callbacks.success) 
     .fail(callbacks.error) 
    }; 

    postEntity = function (data, callbacks) { 
     return dataservice.ajaxRequest('post', routeUrl(this.route), data) 
     .done(callbacks.success) 
     .fail(callbacks.error) 
    }; 

    deleteEntity = function (id, data, callbacks) { 
     return dataservice.ajaxRequest('delete', routeUrl(this.route, id), data) 
     .done(callbacks.success) 
     .fail(callbacks.error) 
    }; 

    // Public:  Return public interface 
    return { 
     setRoute: setRoute, 
     getAllEntities: getAllEntities, 
     getEntitiesById: getEntitiesById, 
     putEntity: putEntity, 
     postEntity: postEntity, 
     deleteEntity: deleteEntity 
    }; 

}); 

Come si può vedere, sto referenziare DataServices/Dataservice, che è in realtà il meccanismo chiamata AJAX nucleo (non mostrato, ma in realtà solo una chiamata jQuery ajax di base in un wrapper).

Quello che sto cercando di fare è di permettere che questo modulo base Dataservice di essere "istanziato" come segue (all'interno di un altro modulo - snippet di codice solo):

define(['dataservices/dataservice_base', 'dataservices/dataservice_base', 'dataservices/dataservice_base'], function (dataservice_profile, dataservice_qualifications, dataservice_subjects) { 

    // Set the service route(s) 
    dataservice_profile.setRoute('/api/profile/'); 
    dataservice_qualifications.setRoute('/api/qualification/'); 
    dataservice_subjects.setRoute('/api/subject/'); 

Come potete vedere, sto cercando di includere lo stesso dataservice_base (definito sopra) per 3 volte, ma nei riferimenti di funzione, sto cercando di fare riferimento a ogni istanza da Vars nome vale a dire:

dataservice_profile, dataservice_qualifications, dataservice_subjects

.. e naturalmente sto cercando di essere in grado di impostare un valore unico setRoute per ognuna di queste istanze da utilizzare ulteriormente nel modulo .. sfruttando al contempo le chiamate comuni (get, puts, posts ecc.).

Ovviamente mi mancano alcune cose qui .. ma qualsiasi aiuto per indicarmi indietro sulla strada sarebbe molto ben accolto !!

Cordiali saluti, David.

risposta

6

Penso che sia necessario includere la dipendenza una sola volta e utilizzare la parola chiave new. Forse hai bisogno di refactoring in modo che le funzioni comuni sono in un modulo base:

define(['dataservices/dataservice'], function (dataservice) { 
    var dataservice_profile = new dataservice(); 
    var dataservice_qualifications = new dataservice(); 
    var dataservice_subjects = new dataservice(); 

    // Set the service route(s) 
    dataservice_profile.setRoute('/api/profile/'); 
    dataservice_qualifications.setRoute('/api/qualification/'); 
    dataservice_subjects.setRoute('/api/subject/'); 

    // define needs to return something 
    return { 
     profile: dataservice_profile, 
     qualifications: dataservice_qualifications, 
     subjects: dataservice_subjects 
    }; 
}); 
3

Sì, cervello-freeze o qualsiasi altra cosa .. problemi di lavorare da solo a volte!

Quindi, come ho detto @asgoth, giustamente ho dovuto schiarirmi le idee e pensare le cose un po '!

ho finito con un modulo dataservice_base rifattorizzati come segue:

define(['dataservices/dataservice'], function (dataservice) { 

    // Set any class/static vars 

    // Set the instance function 
    function dataservice_base(setRoute) { 

     var self = this; 

     self.route = setRoute; 
     console.log('setting route: ' + self.route); 

     function routeUrl(route, id) { 
      console.log('** Setting route to: ' + route); 
      return route + (id || "") 
     } 

     self.getAllEntities = function (callbacks) { 
      return dataservice.ajaxRequest('get', routeUrl()) 
      .done(callbacks.success) 
      .fail(callbacks.error) 
     } 

     self.getEntitiesById = function (id, callbacks) { 
      return dataservice.ajaxRequest('get', routeUrl(self.route, id)) 
      .done(callbacks.success) 
      .fail(callbacks.error) 
     } 

     self.putEntity = function (id, data, callbacks) { 
      return dataservice.ajaxRequest('put', routeUrl(self.route, id), data) 
      .done(callbacks.success) 
      .fail(callbacks.error) 
     } 

     self.postEntity = function (data, callbacks) { 
      return dataservice.ajaxRequest('post', routeUrl(self.route), data) 
      .done(callbacks.success) 
      .fail(callbacks.error) 
     } 

     self.deleteEntity = function (id, data, callbacks) { 
      return dataservice.ajaxRequest('delete', routeUrl(self.route, id), data) 
      .done(callbacks.success) 
      .fail(callbacks.error) 
     } 

    } // eof instance 

    return dataservice_base; 
} 

e naturalmente nuovo come @asgoth menzionati, devo soltanto naturalmente includere un riferimento al modulo dataservice_base, ed esempio esso per i miei bisogni come segue:

define(['dataservices/dataservice_base','viewmodels/viewmodel_profile', 'viewmodels/viewmodel_qualifications', 'viewmodels/viewmodel_subjects', 'app/common'], function (dataservice_base, viewmodel_profile, viewmodel_qualifications, viewmodel_subjects, common) { 

    var dataservice_profile = new dataservice_base('/api/profile/'); 
    var dataservice_qualifications = new dataservice_base('/api/qualification/'); 
    var dataservice_subjects = new dataservice_base('/api/subject/'); 

    // do whatever now with those instance objects... 
} 

SO .. ora tutto funziona!

Immagino che l'unica altra cosa che devo fare è cercare sul processo di pulizia per garantire che questi oggetti siano rilasciati .. tuttavia ci saranno sempre solo pochi .. ma ancora ..

grazie @asgoth nuovo

+2

Ero alle prese con questo concetto. Questa risposta lo rende molto chiaro! ... Suppongo che la chiave qui sia capire che RequireJS restituisce sempre la stessa istanza di un modulo, non importa quante volte lo "richieda". Se il modulo restituisce una funzione di costruzione anziché un oggetto statico, tuttavia, è possibile creare istanze dalla funzione di costruzione utilizzando la nuova parola chiave nel modulo client. La stessa funzione di costruzione viene restituita da RequireJS ogni volta, ma è quello che vogliamo perché è un modello, una classe. È compito del modulo client creare istanze da quella classe. –

+0

"" "Suppongo che la chiave qui sia capire che RequireJS restituisce sempre la stessa istanza di un modulo, non importa quante volte lo" richieda "." "" Quasi. Memorizza nella cache la prima istanza richiesta, ma SOLO se è lo stesso modulo esatto sullo stesso percorso esatto. Questo significa che se hai la stessa lib "xxx" in 2 percorsi diversi (per le diverse parti della tua app), ad esempio: app/modules/foo/xxx e app/modules/bar/xxx, quindi richiedendo ciascuno di portare un istanza diversa. Questo può accadere per es. se hai un package.json diverso per ogni modulo e chiedono la stessa libreria. – Hejazzman

1

tornare solo una funzione invece di un oggetto come questo

return function(){ 
    return { 
     // your public interface goes here 
    }; 
} 

Ora è possibile creare nuove istanze del plugin con new componentName().

Problemi correlati