我想知道我是否可以从服务中调用控制器方法。
我知道Service是单例,我不能将$scope
注入服务。
在我的情况下,我在服务中管理Google地图,并希望在用户右键单击Polygon时打开模式对话框。
据我所知,要打开/创建对话框的新实例,Service必须以某种方式通知控制器执行此操作。
这是一个带有控制器+方法和服务的模板:Template
var myApp = angular.module('myApp', []);
function MyCtrl($scope, gridService, $timeout) {
// how to call "foo" method from service?
$scope.foo = function(){
alert('called from service');
};
}
myApp.service('gridService', ['$timeout', function ( $timeout) {
var grid = {
fetching: false,
pristine: true,
pageType: 'Edit'
}
return {
gridSetup: function () {
return grid;
},
setGridSetup: function (newGrid) {
}
}
}]);
谢谢,
答案 0 :(得分:3)
答案很简单:你没有。
该服务存在操纵数据,没有别的。它真的不应该关心“为什么”它正在做它正在做的事情。您要求服务部门做某事并等待回复。
我个人更喜欢使用promises来解决异步操作(即通知控制器状态更改),因为它受到许多角度服务(如$ http)的大力支持。 但随意使用你想要的回调。
答案 1 :(得分:1)
一种可能的解决方案是拥有一个可以注入网格服务的对话服务。因此,当用户右键单击多边形时,处理程序将在对话框服务上调用open。
以angular ui上的modal服务为例。
答案 2 :(得分:1)
通常您不需要从服务中调用控制器 - 通常,任何控制器都可以使用单个服务,因此服务对它们一无所知。在大多数情况下,对服务的控制器调用会对某些用户的操作作出反应,然后当服务完成其工作(从服务器获取响应等)时,您需要以某种方式更新控制器中的视图。我看到了如何做到的一般方法。
<强> 1。使用回调。
//controller
$scope.onButtonClick = function() {
$scope.label = "wait, loading...";
function onSuccess(result) {
$scope.label = "done! result is " + result;
}
myService.doSomeWork(param1, param2, onSuccess);
}
//service
doSomeWork: function(param1, param2, onSuccess) {
$.get({...}, onSuccess);
}
因此,您为每个操作提供回调。
<强> 2。订阅活动 您可以将jQuery用于订阅/触发事件
//controller
$(myService).on('update', function() {
$scope.lastUpdateTime = new Date();
});
$scope.onButtonClick = function() {
myService.doUpdate();
}
//service
doUpdate: function() {
$.get({...}, function onOk() {
$(this).trigger('update');
});
}
第3。使用承诺 很多内置的角度服务返回promise对象,你也可以使用它们:
//controller
myService.doSomething(param1).then(function(result) {
$scope.result = result;
});
//service
doSomething: function(param1) {
return $http.get({...});
}
<强> 4。分享一些数据
一个示例是$resource
服务 - 例如,当您调用query
方法时,它返回空的类似数组的对象,可以安全地放入范围,然后在http请求完成时用值填充它。
//controller
$scope.options = myService.options;
$scope.onClick = function() { myService.update() }
//service
options: [],
update: function() {
var self = this;
$http.get({...}).success(function(res) {
self.options.splice(0, self.options.length); //to keep same array
self.options.push.apply(self.options, res.data.options);
});
}
在所有这些情况下,服务和控制器是分开的,服务可以与任何控制器一起使用,如果以某种方式更改控制器/视图部分,您可以轻松地在不会中断的服务上编写单元测试。