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?

MJV
quelle
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.

Aladdin Mhemed
quelle
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.

John Braxler
quelle
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.

Sleenee
quelle
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.

Angulord
quelle
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);
  };
});
Viktor Hunko
quelle
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);**
    ...
  };
});
Oss Entwickler
quelle
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'
    }
}

})

Azmeer
quelle
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;

 }
 ]);`
PratikT
quelle
0
angular.module('myService').service('myService', function() {
    return {
      myFunc2: function(param) {
        return foo + myFunc1(param);
      }
    };
    function myFunc1(param){
        ...
    };
});
Vijay
quelle
-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;
    }
}
Riza
quelle
-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;
});    
Kunal
quelle