我有一个带控制器和服务的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
答案 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。