我的应用程序中有以下服务:
uaInProgressApp.factory('uaProgressService', function(uaApiInterface, $timeout, $rootScope){ var factory = {}; factory.taskResource = uaApiInterface.taskResource() factory.taskList = []; factory.cron = undefined; factory.updateTaskList = function() { factory.taskResource.query(function(data){ factory.taskList = data; $rootScope.$digest console.log(factory.taskList); }); factory.cron = $timeout(factory.updateTaskList, 5000); } factory.startCron = function () { factory.cron = $timeout(factory.updateTaskList, 5000); } factory.stopCron = function (){ $timeout.cancel(factory.cron); } return factory; });
然后在这样的控制器中使用它:
uaInProgressApp.controller('ua.InProgressController', function ($scope, $rootScope, $routeParams, uaContext, uaProgressService) { uaContext.getSession().then(function(){ uaContext.appName.set('Testing house'); uaContext.subAppName.set('In progress'); uaProgressService.startCron(); $scope.taskList = uaProgressService.taskList; }); } );
因此,基本上我的服务factory.taskList每5秒更新一次,因此我将其链接factory.taskList到$scope.taskList。然后$apply,我尝试了类似的不同方法,$digest但是对factory.taskList所做的更改未反映在控制器和视图中$scope.taskList。
factory.taskList
$scope.taskList
$apply
$digest
它在我的模板中仍然为空。您知道我如何传播这些变化吗?
虽然使用$watch可以解决问题,但这不是最有效的解决方案。您可能想要更改在服务中存储数据的方式。
$watch
问题是您taskList每次在为范围分配指向旧位置的范围内分配新值时都替换与之关联的内存位置。您可以在这种情况下看到这种情况。
taskList
首次加载插件时,使用Chrome拍摄堆快照,单击按钮后,您将看到示波器指向的内存位置从未更新,而列表指向了另一个内存位置。
您可以通过让服务中包含一个包含可能更改的变量的对象(如data:{task:[], x:[], z:[]})来轻松解决此问题。在这种情况下,永远不要更改“数据”,但可以随时更改其任何成员。然后,您可以将此数据变量传递给范围,并且只要不通过尝试将“数据”分配给其他变量来覆盖它,只要数据中的字段发生变化,范围就将知道并正确更新。
data:{task:[], x:[], z:[]}
该示例显示了使用上面建议的修复程序运行的相同示例。在这种情况下,无需使用任何观察程序,并且一旦发生未在视图上进行某些更新的情况,您知道您需要做的就是运行一个作用域$apply来更新视图。
这样,您便无需观察者经常比较变量的更改和在需要监视许多变量的情况下涉及的丑陋设置。这种方法的唯一问题是,您在视图(html)上将拥有“数据”。在所有以前只有变量名的地方加上前缀。