2013-03-08 22 views
30

Sono abbastanza nuovo a angularjs e non sono in grado di trovare alcuna documentazione o esempi per questo. Quello che sto cercando di fare è estendere un servizio di base in modo da poter utilizzare i metodi definiti nel servizio di base da altri servizi. Quindi, per esempio, dire che ho un servizio di base come segue.come posso estendere un servizio

angular.module('myServices', []). 

    factory('BasicService', function($http){ 
     var some_arg = 'abcd' 
     var BasicService = { 
      method_one: function(arg=some_arg){ /*code for method one*/}, 
      method_two: function(arg=some_arg){ /*code for method two*/}, 
      method_three: function(arg=some_arg){ /*code for method three*/}, 
     }); 
     return BasicService; 
    } 
); 

Ora voglio definire un servizio esteso che si estende da quanto sopra BasicService in modo che posso usare metodi definiti sotto il BasicService dal mio servizio esteso. Forse qualcosa di simile:

factory('ExtendedService', function($http){ 
     var ExtendedService = BasicService(); 
     ExtendedService['method_four'] = function(){/* code for method four */} 
     return ExtendedService; 
    } 

risposta

21

tuo ExtendedService dovrebbe iniettare il BasicService al fine di essere in grado di accedervi. Inoltre, BasicService è un oggetto letterale, quindi non è possibile chiamarlo come funzione (BasicService()).

.factory('ExtendedService', function($http, BasicService){ 
    BasicService['method_four'] = function(){}; 
    return BasicService; 
} 
+0

perfetto grazie, assolutamente quello che stavo cercando. – Amyth

+0

Ho ragione nel dire che questo è il metodo migliore se consideriamo che BasicService sia astratto? Perché in questo caso non useremo mai BasicService, solo ExtendedService, quindi va bene estenderlo letteralmente. – Floris

+0

Questo metodo è davvero ok? Dato che i servizi sono singleton, ciò significa che la modifica su BasicService sarà permanente, quindi verrà modificato anche BasicService. Non sarebbe meglio creare una copia di BasicService e restituire la versione estesa di quella copia? – Razvan

3

Scusate se postare qui ma potrebbe essere un buon posto per farlo. Mi riferisco a questo post

guardare fuori per estendere un servizio/fabbrica perché sono Singleton in modo da poter estendere un servizio/fabbrica di una volta.

'use strict'; 
      angular.module('animal', []) 
       .factory('Animal',function(){ 
         return { 
          vocalization:'', 
          vocalize : function() { 
           console.log('vocalize: ' + this.vocalization); 
          } 
         } 

       }); 
       angular.module('dog', ['animal']) 
        .factory('Dog', function (Animal) { 
         Animal.vocalization = 'bark bark!'; 
         Animal.color = 'red'; 
         return Animal; 
        }); 

       angular.module('cat', ['animal']) 
        .factory('Cat', function (Animal) { 
         Animal.vocalization = 'meowwww'; 
         Animal.color = 'white'; 
         return Animal; 
        }); 
       angular.module('app', ['dog','cat']) 
       .controller('MainCtrl',function($scope,Cat,Dog){ 
        $scope.cat = Cat; 
        $scope.dog = Dog; 
        console.log($scope.cat); 
        console.log($scope.dog); 
        //$scope.cat = Cat; 
       }); 

, ma se vi piace

'use strict'; 
      angular.module('animal', []) 
       .factory('Animal',function(){ 
        return function(vocalization){ 
         return { 
          vocalization:vocalization, 
          vocalize : function() { 
           console.log('vocalize: ' + this.vocalization); 
          } 
         } 
        } 
       });  
       angular.module('app', ['animal']) 
        .factory('Dog', function (Animal) { 
         function ngDog(){ 
          this.prop = 'my prop 1'; 
          this.myMethod = function(){ 
           console.log('test 1'); 
          } 
         } 
         return angular.extend(Animal('bark bark!'), new ngDog()); 
        }) 
        .factory('Cat', function (Animal) { 
         function ngCat(){ 
          this.prop = 'my prop 2'; 
          this.myMethod = function(){ 
           console.log('test 2'); 
          } 
         } 
         return angular.extend(Animal('meooow'), new ngCat()); 
        }) 
       .controller('MainCtrl',function($scope,Cat,Dog){ 
        $scope.cat = Cat; 
        $scope.dog = Dog; 
        console.log($scope.cat); 
        console.log($scope.dog); 
        //$scope.cat = Cat; 
       }); 

funziona

+1

Un buon chiarimento ma l'angular.extend() si occupa di questo in modo più semplice creando una copia del servizio. – Alkaline

68

più pulito e più modo imperativo

.factory('ExtendedService', function($http, BasicService){ 

    var extended = angular.extend(BasicService, {}) 
    extended.method = function() { 
     // ... 
    } 
    return extended; 
} 
+10

Penso che sia meglio estendere l'oggetto vuoto invece del servizio originale: 'var extended = angular.extend ({}, BasicService)'.Anche 'copia' creerà una nuova istanza invece di estenderla con la sua copia superficiale – havenchyk

+0

Perfetto !!! Molto pulito ... –

16

A mio parere, un modo migliore:

.factory('ExtendedService', function($http, BasicService){ 
    var service = angular.copy(BasicService); 

    service.methodFour = function(){ 
     //code for method four 
    }; 

    return service; 
}); 

Qui almeno non cambia il servizio ereditato.

+0

Sono d'accordo, usare copy() ha molto più senso perché non stai cambiando il servizio ereditato. –

-1

Per espandere sulla risposta di Stewie, si potrebbe anche effettuare le seguenti operazioni:

.factory('ExtendedService', function($http, BasicService){ 
    var service = { 
     method_one: BasicService.method_one, 
     method_two: BasicService.method_two, 
     method_three: BasicService.method_three, 
     method_four: method_four 
    }); 

    return service ; 

    function method_four(){ 

    } 
} 

Questo ha il vantaggio che il servizio originale non viene alterato, pur mantenendo sue funzionalità. È inoltre possibile scegliere di utilizzare le proprie implementazioni in ExtendedService per gli altri 3 metodi da BasicService.

+0

Non il poster, ma qualcuno può spiegare perché questa soluzione è stata downvoted? Mi sta bene. – Floris

+0

Sembra che questo post sia stato downvoted perché è necessario elencare metodi e campi ottenuti dall'oggetto padre. Questa è una cattiva pratica per alcune ragioni. Anche tecnicamente questa non è pura eredità. –

1

ho scritto un $ estendono provider che utilizza Backbone di estendere sotto il cofano - in modo da ottenere sia il prototipo e proprietà statica che si estende nel caso in cui ne hai bisogno - più si ottiene genitore/figlio costruttori - vedere gist @https://gist.github.com/asafebgi/5fabc708356ea4271f51

Problemi correlati