2013-01-08 11 views
6

Ich vermisse offensichtlich etwas Konzept/Verständnis und definitiv Javascript OO Grundlagen!Kann ich mehrere Instanzen eines RequireJS-Moduls haben?

I am loving RequireJS verwenden, und mein Web-App sieht jetzt eher wie eine strukturierte App jetzt statt einem ganzen Haufen von verrücktem Code.

Ich habe nur Mühe zu verstehen, wie/wenn das Folgende möglich ist.

Ich habe ein Modul, das als Basisdatendienst-Modul dataservice_base wie folgt genannt wirkt:

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 
    }; 

}); 

Wie Sie sehen können, bin ich Referenzierung Datendienste/Datendienst, der Mechanismus AJAX-Aufruf tatsächlich der Kern (nicht gezeigt, aber wirklich nur grundlegende jQuery Ajax Aufruf in einem Wrapper).

Was ich versuche, dieses Basisdatendienst-Modul zu tun ist, damit seine „instanziert“ wie folgt (in einem anderen Modul - Snippet-Code nur):

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/'); 

Wie Sie sehen können, ich versuche zu schließen die gleichen dataservice_base (oben definiert) 3-mal, aber in den Funktionsaufrufen, ich versuche, von dem Namen vars für jede Instanz zu verweisen, dh:

dataservice_profile, dataservice_qualifications, dataservice_subjects

.. und natürlich versuche ich einen einzigartigen setRoute Wert für jede dieser Instanzen zu setzen, um weiter im Modul zu verwenden .. während die gemeinsamen Aufrufe (get, puts, posts usw.) genutzt werden.

Offensichtlich fehlen mir ein paar Dinge hier .. aber jede Hilfe mich auf dem Weg zum Punkt zurück sehr dankbar empfangen werden würde !!

Mit freundlichen Grüßen, David.

Antwort

6

Ich glaube, Sie brauchen Ihre Abhängigkeit nur einmal aufzunehmen und verwenden Sie das new Schlüsselwort. Möglicherweise müssen Sie Refactoring, so dass die gemeinsamen Funktionen sind in einem je Modul:

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

Ja, Gehirn-freeze oder was auch immer .. Probleme von allein manchmal zu arbeiten!

So, wie @asgoth erwähnt, hatte zu Recht meiner Meinung und denkt, die Dinge durch ein Bit löschen!

ich mit einem Wieder einkalkuliert dataservice_base Modul endete wie folgt:

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; 
} 

und natürlich wieder als @asgoth erwähnt, ich brauche nur zu natürlich ein Verweis auf das dataservice_base Modul enthalten, und es Instanz für meine Bedürfnisse wie folgt:

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 .. jetzt alles funktioniert!

Ich denke, die einzige andere, was ich tun muss, ist auf der Suche nach oben über den Prozess Reinigung dieser Objekte, um sicherzustellen, freigesetzt werden .. aber es wird .. aber noch immer nur wenige sein ..

dank @asgoth wieder

+2

Ich hatte mit diesem Konzept zu kämpfen. Diese Antwort macht es sehr deutlich! ... Ich denke, der Schlüssel hier ist zu verstehen, dass RequireJS immer die gleiche Instanz eines Moduls zurückgibt, egal wie oft Sie es "benötigen". Wenn Ihr Modul jedoch eine Konstruktorfunktion anstelle eines statischen Objekts zurückgibt, können Sie Instanzen mit dem neuen Schlüsselwort im Clientmodul aus der Konstruktorfunktion erstellen. Dieselbe Konstruktorfunktion wird jedes Mal von RequireJS zurückgegeben, aber das ist es, was wir wollen, weil es eine Vorlage, eine Klasse ist. Es ist die Aufgabe des Clientmoduls, Instanzen aus dieser Klasse zu erstellen. –

+0

"" "Ich nehme an, der Schlüssel hier ist zu verstehen, dass RequireJS immer dieselbe Instanz eines Moduls zurückgibt, egal wie oft Sie es" benötigen "." " Fast. Es speichert die erste erforderliche Instanz, aber NUR, wenn es sich um genau dasselbe Modul auf demselben Pfad handelt. Dies bedeutet, dass wenn Sie die gleiche lib "xxx" in zwei verschiedenen Pfaden (für verschiedene Teile Ihrer App) haben, wie: app/modules/foo/xxx und app/modules/bar/xxx, dann jede während erfordern eine bringen andere Instanz. Dies kann z.B. Wenn Sie für jedes Modul eine andere package.json-Datei haben und diese nach derselben Bibliothek fragen. – Hejazzman

1

nur eine Funktion statt eines Objekts zurückgeben wie diese

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

Jetzt können Sie neue Instanzen des Plug-In mit new componentName() erstellen.

Verwandte Themen