如何在角度应用程序中从服务调用控制器中的函数

时间:2016-03-14 16:05:41

标签: javascript angularjs

我有一个带控制器和服务的Angular应用程序。我从控制器调用服务,服务进行后端调用,并应调用控制器中的另一个函数。我能够从控制器调用该服务,但无法调用控制器中的函数。

这是代码。控制器:

(function(){
  angular.module("addressModule")

    // The controller for the standardized Address
    .controller('myController', ['$resource','myService', myControllerFunction]);

    myControllerFunction.$inject = ['addressConfig', 'myService', '$resource'];

    function myControllerFunction (addressConfig, myService, $resource, $scope) {
      var vm = this;

      // cannot show what the model is
      vm.model = "some model";
      myService.callGISFromService(vm.model);

      this.callFunctionInController = function(){
        console.log("The controller function is called");
      }
    }
})();

服务的代码是

(function(){

    angular.module('addressModule')
        .service('myService', ['$resource',  myServiceFunction]);

    myServiceFunction.$inject = ['$resource'];

    function myServiceFunction ($resource) {

        this.callGISFromService = function (model) {
            var urlForTheGISCall = "some URL";
            var resource = $resource(urlForTheGISCall);
            console.log("control is in the service");

            resource.get().$promise
            .then(function successCallback(response) {

                this.callFunctionInController();

            }), function errorCallback(response) {
                console.log("the backend call did not work");

            }
        };
    }
})();

我能够进行后端调用并获取所需数据,但无法在控制器中调用该函数。

控制台上的错误:

TypeError: this.callFunctionInController is not a function

2 个答案:

答案 0 :(得分:3)

您可能需要查看this post,它解释了如何使用$broadcast来建立服务控制器之间的通信。

您还可以将服务中的函数转换为异步函数,以便控制器知道函数何时成功完成或出错。它看起来像这样:

(function(){

angular.module('addressModule')

.service('myService', ['$resource', '$q',  myServiceFunction]);

        myServiceFunction.$inject = ['$resource', '$q'];

        function myServiceFunction ($resource) {

        this.callGISFromService = function (model) {

            var deferred = $q.defer();

            var urlForTheGISCall = "some URL";

            var resource = $resource(urlForTheGISCall);
            console.log("control is in the service");

            resource.get().$promise
            .then(function successCallback(response) {

                deferred.resolve('success');

            }), function errorCallback(response) {
                deferred.reject('error');
            }

              return deferred.promise;
        };
    }
})();

这使得您可以在控制器中调用您的函数,如下所示:

(function(){
    angular.module("addressModule")
    // The controller for the standardized Address

        .controller('myController', ['$resource','myService', myControllerFunction]);

        myControllerFunction.$inject = ['addressConfig', 'myService', '$resource'];

        function myControllerFunction (addressConfig, myService, $resource, $scope) {

            var vm = this;
            // cannot show what the model is
            vm.model = "some model";
            myService.callGISFromService(vm.model).then(function(success){
                function(){
                    console.log("The controller function is called");
            }
            });

}
})();

我个人会选择第二种选择,因为它比使用广播更优雅,更轻巧。在你的应用程序中分配广播可能会让它变得非常混乱和难以阅读。关于异步函数的For more info,请查看angularjs文档

答案 1 :(得分:1)

这是JavaScript回调模式。您还可以使用Observer模式。

我们可以使用subscribe方法创建一个Observable服务。此方法将接受来自订阅控制器的function

Observable.$inject = ['$http'];
function Observable($http) {
    this.$http = $http;
    this.subscribers = [];
}

Observable.prototype.subscribe = function(fn) {
    this.subscribers.push(fn);
}

Observable.prototype.getSomething = function() {

    var self = this;
    this.$http.get('/something').then(function() {
        self.subscribers.forEach(function(fn) { fn() })));
}

app.service('observable', Observable);

然后在您的控制器中,您可以订阅更新:

ObserverController = ['observale'];
function ObserverController(observable) {
    observable.subscribe(this.callback);
}

ObserverController.prototype.callback = function() {
    // this is called from the Observable service
}

app.controller('ObserverController', ObserverController);

在您的控制器中,您明确订阅了从Observable服务获取更新。每次调用服务中的getSomething方法时,都会调用先前传递给subscribe方法的函数。

通常,Observable会将对象/值传递给Observer。