我可以想到两个基本的方法,我猜(一个也可能是两个)是错误的:
>控制器将数据存储在$scope变量中,并执行setInterval或$timeout来调用服务的方法以获取新数据,然后更新变量.
>服务将数据存储在自己的变量/属性中,并定期调用其自身以获取新数据.并且控制器以某种方式监视/监听服务属性以知道何时更新视图.
为了这个问题的目的,考虑一个具体的例子可能是有帮助的.如果HTTP请求失败,我想向视图/用户显示错误.所以假设一个需要居住在某处的errorMsg变量.它应该在控制器中生存吗?在这种情况下,服务需要每次返回该值.或者它应该在服务中,控制器以某种方式观看它.
我已经尝试了第一种方法,似乎在控制器中导致了大量的逻辑,主要是在遵循服务方法的then()中.我的直觉是#2是正确的方法.但是我有点不清楚控制器应该如何监听/观看服务.提前致谢.
解决方法
The controller stores the data and queries the service
这叫拉.您正在有效地创建您在控制器中轮询的服务器响应流
The service stores the data and the controller watches it
这被称为推.您正在有效地创建一个结果流,并通知消费者更改,而不是寻找它们.
这些都是您的问题的有效方法.选择一个你觉得更容易理解的.我个人认为,第二个是更清洁的,因为你不必在控制器中注意.这应该给你一个一般的想法:
function getServerState(onState){ return $http.get("/serverstate").then(function(res){ onState(res.data);// notify the watcher }).catch(function(e){/*handle errors somehow*/}) .then(function(){ return getServerState(onState); // poll again when done call }); }
你可以这样消费:
getServerState(function(state){ $scope.foo = state; //since it's in a digest changes will reflect });
我们的最后一个问题是泄漏范围,因为代码不在控制器上,我们将一个回调注册到一个不再存在的范围.因为我们不能使用有趣的ES6设施 – 我们必须为getServerState方法返回值提供一个“我已经完成”的句柄,例如一个.done属性,你将在一个范围中调用destroy事件.