Виклик функції в сервісі AngularJS з тієї ж служби?


77

У мене є послуга AngularJS, визначена таким чином

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

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

і я хотів би викликати першу функцію як поза службою (яка чудово працює myService.publicFunction(xxx)), так і з іншої функції в тій самій службі, тобто anotherPublicFunction.Жодна з this.publicFunction(param)або myService.publicFunction(param)не працюватиме з другої функції, і я можу це зрозуміти.


EDIT:
Насправді вся проблема була спричинена тим, що ви не можете відтворити лише на моєму прикладі. Я передав другу функцію як параметр зворотного виклику іншій функції в окремому контролері, і коли вона викликається, посилання на thisне працює.

Напр

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

не вдається всередині, anotherPublicFunctionоскільки thisне може бути вирішена.

Я написав Plunker, щоб показати проблему: http://plnkr.co/edit/rrRs9xnZTNInDVdapiqF?p=info

(Я все одно залишу питання тут, якщо це допоможе комусь іншому.)


Я знаю, що міг би обійти проблему, використовуючи посилання на службу або першу функцію, подібну до цієї

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

або це

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

але обидва здаються брудними хаками.

Чи є в цьому випадку хороший спосіб викликати першу функцію з другої? Або я в першу чергу роблю щось зовсім не так, щоб мати таку послугу?

Я знайшов ці запитання з хорошими відповідями:

але вони відрізняються від моєї проблеми, оскільки одна з них має окрему внутрішню функцію, яку слід було викликати, а інша використовує фабрику замість послуги.

РЕДАГУВАТИ:

Опублікувавши це, я відразу зрозумів, що можу зробити і таке:

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

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

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

що здається не таким поганим, як інші варіанти дотепер ... Чи є кращі підходи?


1
Чому ви називаєте var ms = this;(що частіше пишуть як var self = this;) "брудним хаком"?
Михайло Батцер

Це лише питання особистого смаку і випливає з мого походження (особливо на Java). Використання нового "вказівника" на іншу змінну thisв тому ж обсязі просто дивно ... Але thisце спеціальне посилання, і JavaScript має такий тип лексичного закриття, тому це одна з тих речей, яку я, мабуть, повинен просто прийняти та прийняти під час написання коду JS . Коли був у Римі тощо
MJV

Відповіді:


40

Я думаю, що найкращий спосіб - це йти так:

var myFunctions = 
{

    myFunc1: function(param) {

    },

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

}
return myFunctions;

оскільки я думаю, що якщо ви використовуєте це , це може вступити в конфлікт із сферою, де ви користуєтесь послугою.


Остаточне редагування OP - це те, що працює. Просто оголосіть var foo = function () {...} та викличте foo () у рядку, як bar = function () {... foo () ...}
wsgeorge

це послуга, ви використовуєте "це"
bokkie

33

Я зіткнувся з цією проблемою у своєму власному кутовому кодуванні і вирішив використовувати таку форму рішення:

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

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

Я віддав перевагу такому підходу, тому що у своєму коді я використовую publicFunction, а всередині anotherPublicFunction я цикую декілька параметрів, яким потрібно викликати publicFunction як частину процесу.


1
дуже просто. Відмінно!
Умар

8

Звучить добре, але що ти робиш, коли послуги thisбільше не існує =?

Це має місце в наступному прикладі:

return {

        myFunc1: function(param) {

        },

        myFunc2: function(param) {

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

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

            }       
        }

}

Через function(v) {вас ви зараз в іншій функції у цій функції, і це вже не служба, а вікно.


4

Ви можете просто повернути об’єкт із вашої служби, наприклад

return {

    myFunc1: function(param) {

    },

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

}

Таким чином, ви отримуєте доступ до нього ззовні за допомогою service.myFunc1і зсередини його внутрішніх функцій.


Дякую за це. Коли я спробував це у своєму коді, а потім у Plunker, я зрозумів, що початкова проблема була лише побічним ефектом чогось іншого. Здається, мій "проблемний" код насправді працює так, як я представив його у своєму питанні.
MJV

4

Ви можете встановити 'this' як змінну

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

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

1

Ну, просто створіть ще два покажчики / змінні функції для ваших службових функцій з локальними змінними в службі і використовуйте їх для виклику службових функцій всередині однієї служби:

*

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

ось як я реалізував:

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

})


0

Нижче рішення працювало для мене: -

 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

Найкращий і найпростіший спосіб зателефонувати:

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

Якщо ви хочете використовувати заводську декларацію замість служби, ви можете: -

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;
});    
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.