Angularjs服务回调以更新控制器的作用域

Angularjs服务回调以更新控制器的作用域,angularjs,angularjs-scope,Angularjs,Angularjs Scope,具有第三方库回调函数的服务: mbAppModule.service('aService', function ($http) { this.data={"somedata":0}; var m3rdPartLib="init"; // init m3rdPartLib.on('timeupdate', function() { this.data.somedata=1; }); } 和一个控制器 mbAppModule.control

具有第三方库回调函数的服务:

mbAppModule.service('aService', function ($http) {
    this.data={"somedata":0};
    var m3rdPartLib="init";  // init    
    m3rdPartLib.on('timeupdate', function() {
        this.data.somedata=1;
    });
}
和一个控制器

mbAppModule.controller({
    MController: function ($scope, $http, mService) {
        $scope.mService= mService;    
    });
});
html页面

{{mService.data.somedata}}
问题: m3rdPartLib.on()是一个第三方库回调函数,我正在服务中使用它。我想在它更新时在ui中显示它。在回调时,值会发生更改,但不会反映在ui上


阅读一些文档,发现$rootScope。可以调用$apply,但我在服务中没有$scope/$rootScope的引用。

使用
$scope.$watch
函数。看看我的眼睛。我没有你的库,所以我只模拟它-值在5秒后从0变为1。

你可以依赖
$rootScope
并在你的服务中调用apply

mbAppModule.service('aService', ["$http", "$rootScope", function ($http, $rootScope) {
    this.data = {
        "somedata": 0
    };
    var m3rdPartLib = "init"; // init    
    m3rdPartLib.on('timeupdate', function () {
        $rootScope.$apply(function(){
            this.data.somedata = 1;
        });
    });
}]);

我需要从服务中更新一个输入字段,因为它有监听器,而没有监听器会随机动态地更改数据

这也可用于调用控制器中的作用域函数:

//scope will be set to current scope of a controller
//which has an ng-view containing this element    
var scope = angular.element('#input-element').scope();
//wrap changes in an apply call to make sure view and model are consistent
scope.$apply(function() {
    scope.object.data = value;
});

多亏了这篇文章:

如果您在服务中使用scope,那么这是一个很好的指示器,表明您正在破坏SRP,因为您的服务应该只向您的控制器检索数据。 我的建议是你可以这样做

mbAppModule.service('aService', ["$http", "$rootScope", function ($http, $rootScope) {
  this.data = {
    "somedata": 0
  };
  var m3rdPartLib = "init"; // init    
  this.GetPartLib = function () { 
    return m3rdPartLib;
  }
}]);

mbAppModule.controller({
  MController: function ($scope, $http, mService) {
  this.GetPartLib = function (){ 
    mService.on('timeupdate', function() {
     this.data.somedata=1;
    });
  }
});

不!这没用$超时是angular的一部分,因此它将自动调用apply和digest来更新作用域。好的,请检查此项。它有用吗?我使用事件而不是手表。@mchrobok使用$watch在这种情况下没有用处。首先,在模板中使用
service.data.somedata
也可以反映更改,而不需要$watch。在第二种情况下,如果在模板中使用
service.data.somedata
,而无需再次使用事件机制,则在超时函数中调用
$rootScope.$apply()
也将触发更改。只要引用有效并触发摘要循环,就会更新该值。我觉得如果服务不需要了解UI就更好了。在我看来,这似乎应该落在控制器上。通过在您的服务中创建一个回调来更新UI,这是很容易做到的。这对一些人来说可能是显而易见的,但对其他人来说,尤其是初学者,这一点并不明显。