Eine Funktion im AngularJS-Dienst vom selben Dienst aus aufrufen?


77

Ich habe einen AngularJS-Dienst wie folgt definiert

angular.module('myService').service('myService', function() {
  this.publicFunction(param) {
    ...
  };

  this.anotherPublicFunction(param) {
    // how to call publicFunction(param)?
    ...
  };
});    

und ich möchte die erste Funktion sowohl von außerhalb des Dienstes (was gut funktioniert myService.publicFunction(xxx)) als auch von einer anderen Funktion im selben Dienst aufrufen , d anotherPublicFunction. h .Keiner von beiden funktioniert innerhalb der zweiten Funktion this.publicFunction(param)oder myService.publicFunction(param)wird nicht funktionieren, und das kann ich verstehen.


EDIT:
Eigentlich wurde das ganze Problem durch etwas verursacht, das man mit meinem Beispiel allein nicht reproduzieren kann. Ich habe die zweite Funktion als Rückrufparameter an eine andere Funktion in einem separaten Controller übergeben, und wenn sie aufgerufen wird, thisfunktioniert der Verweis auf nicht.

Z.B

anotherService.someCall('a', 123, myService.anotherPublicFunction);

schlägt innen fehl, anotherPublicFunctionweil thisnicht gelöst werden kann.

Ich habe einen Plunker geschrieben, um das Problem zu zeigen: http://plnkr.co/edit/rrRs9xnZTNInDVdapiqF?p=info

(Ich werde die Frage immer noch hier lassen, falls sie jemand anderem hilft.)


Ich weiß, dass ich das Problem umgehen kann, indem ich einen Verweis auf den Dienst oder die erste Funktion wie diese verwende

var ms = this;
this.anotherPublicFunction(param) {
  ms.publicFunction(param);
  ...
};

oder dieses

var pf = this.publicFunction;
this.anotherPublicFunction(param) {
  pf(param);
  ...
};

aber beide scheinen wie schmutzige Hacks.

Gibt es in diesem Fall eine gute Möglichkeit, die erste Funktion von der zweiten aufzurufen? Oder mache ich überhaupt etwas völlig falsch, um einen solchen Service zu haben?

Ich fand diese Fragen mit guten Antworten:

Sie unterscheiden sich jedoch von meinem Problem, da einer von ihnen eine separate interne Funktion hat, die aufgerufen werden sollte, und der andere eine Fabrik anstelle eines Dienstes verwendet.

BEARBEITEN:

Nachdem ich dies gepostet hatte, wurde mir sofort klar, dass ich das auch tun könnte:

var actualWork = function(param) {
  ...
}

this.publicFunction(param) {
  actualWork(param);
};

this.anotherPublicFunction(param) {
  actualWork(param);
  ...
};

Das scheint nicht ganz so schlimm zu sein wie die anderen Optionen bisher ... Gibt es bessere Ansätze?


1
Warum nennst du var ms = this;(was öfter als geschrieben wird var self = this;) "einen schmutzigen Hack"?
Mikhail Batcer

Es ist nur eine Frage des persönlichen Geschmacks und stammt aus meinem Hintergrund (insbesondere in Java). Die Verwendung eines neuen "Zeigers" auf eine andere Variable thisim selben Bereich fühlt sich einfach komisch an ... Aber es thisist eine spezielle Referenz und JavaScript hat diese Art von lexikalischem Abschluss, daher ist es eines der Dinge, die ich beim Schreiben von JS-Code wahrscheinlich nur akzeptieren und akzeptieren sollte . Wenn in Rom usw.
MJV

Antworten:


40

Ich denke, der beste Weg ist, so zu gehen:

var myFunctions = 
{

    myFunc1: function(param) {

    },

    myFunc2: function(param) {
       return foo + myFunctions.myFunc1(param)// do some stuff with the first function        
    }

}
return myFunctions;

weil ich denke, wenn Sie dies verwenden , kann es zu Konflikten mit dem Umfang kommen, in dem Sie den Dienst verwenden.


Die endgültige Bearbeitung von OP funktioniert. Deklarieren Sie einfach var foo = function () {...} und rufen Sie foo () in bar wie bar = function () {... foo () ...} auf
wsgeorge

Es ist ein Dienst, Sie verwenden "dies"
Bokkie

33

Ich bin innerhalb meiner eigenen Winkelcodierung auf dieses Problem gestoßen und habe mich für diese Form der Lösung entschieden:

angular.module('myService').service('myService', function() {
  var myService = this;
  myService.publicFunction(param) {
    ...
  };

  myService.anotherPublicFunction(param) {
    myService.publicFunction(param);
    ...
  };
});

Ich habe diesen Ansatz bevorzugt, weil ich in meinem Code publicFunction verwende und innerhalb einer anderen PublicFunction mehrere Parameter durchlaufe, die publicFunction als Teil des Prozesses aufrufen müssen.


1
sehr einfach. Ausgezeichnet!
Umar

8

Hört sich gut an, aber was machen Sie, wenn der Service thisnicht mehr =verfügbar ist?

Dies ist im folgenden Beispiel der Fall:

return {

        myFunc1: function(param) {

        },

        myFunc2: function(param) {

            scope.$watchCollection(param,function(v) {

              return foo + this.myFunc1(param)// do some stuff with the first function 

            }       
        }

}

Weil function(v) {Sie sich jetzt in einer anderen Funktion innerhalb der Funktion befinden und dies nicht mehr der Dienst, sondern das Fenster ist.


4

Sie können einfach ein Objekt aus Ihrem Dienst wie zurückgeben

return {

    myFunc1: function(param) {

    },

    myFunc2: function(param) {
       return foo + this.myFunc1(param)// do some stuff with the first function        
    }

}

Damit greifen Sie von außen mit service.myFunc1und von innen auf seine internen Funktionen zu.


Danke dafür. Als ich dies in meinem Code und dann in einem Plunker ausprobierte, stellte ich fest, dass das ursprüngliche Problem nur ein Nebeneffekt von etwas anderem war. Es scheint, dass mein "problematischer" Code tatsächlich so funktioniert, wie ich ihn in meiner Frage dargestellt habe.
MJV

4

Sie können 'this' als Variable festlegen

angular.module('myService').service('myService', function() {
  var that = this;
  this.publicFunction(param) {
    ...
  };

  this.anotherPublicFunction(param) {
    that.publicFunction(param);
  };
});

1

Erstellen Sie einfach zwei weitere Zeiger / Funktionsvariablen für Ihre Servicefunktionen mit lokalen Variablen im Service und verwenden Sie diese, um die Servicefunktionen innerhalb desselben Service aufzurufen:

* *

angular.module('myService').service('myService', function() {
  **var ref1, ref2;**
  this.publicFunction = **ref1** = function(param) {
    ...
  };
  this.anotherPublicFunction = **ref2** = function(param) {
    // how to call publicFunction(param)?
    **ref1(argument);**
    ...
  };
});

0

So habe ich implementiert:

.service('testSvc', function () {
return {
    f1: function (v1) {
        alert('f1 > v1=' + v1);
    },
    f2: function (v2) {
        alert('f2 > v2=' + v2);
        this.f1('az'); //use 'this'
    }
}

})


0

Die folgende Lösung hat bei mir funktioniert: -

 angular.module('myService').service('myService', function() {

    var self= {
        this.publicFunction(param) {
 ...
 };

 this.anotherPublicFunction(param) {
 // You can call the publicfunction like below
 self.publicFunction(param);
 ...
 };
 return self;

 }
 ]);`

0
angular.module('myService').service('myService', function() {
    return {
      myFunc2: function(param) {
        return foo + myFunc1(param);
      }
    };
    function myFunc1(param){
        ...
    };
});

-1

Der beste und einfachste Weg, um anzurufen, ist:

myapp.service("SomeService", function ($http) {

    this.func1 = function (params) {
        // Some thing the service returns
        return something;
    }

    this.func2 = function (params) {
        // Some thing the service returns
        var resp = this.func1(params);
        return something;
    }
}

-1

Wenn Sie die Werksdeklaration anstelle des Service verwenden möchten, können Sie:

angular.module('myService').factory('myService', function() {
  var myService = {};
  myService.publicFunction = function(param) {
    ...
  };

  myService.anotherPublicFunction = function(param) {
    // call publicFunction(param) like so
    myService.publicFunction(param);
  };

  return myService;
});    
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.