我是AngularJS的新手,并且我和KnockoutJS一起工作了很多,因为当Angular能够并且无法跟踪变化时,我仍然无法理解。
我正在构建一个应用程序,它将拥有一组基础数据,最初我将轮询和更新,但稍后将改进从服务器推送。然后,应用中的所有数据都将根据此数据进行转换或过滤。所以我有一个获取数据的服务,也可以获取数据的常用过滤版本,如下所示:
.factory('Scores', function ($resource, Utils, $q, $interval, $filter) {
var scoresResource = $resource('http://localhost:8000/scores'),
scoresData = [];
$interval(function () {
scoresResource.query(function (newScores) {
scoresData.length = 0;
angular.forEach(newScores, function (dataEntry) {
scoresData.push(dataEntry);
});
})
}, Utils.TIMES.SHORT);
return {
getAll: function () {
var deferred = $q.defer();
if (scoresData.length > 0) {
deferred.resolve(scoresData);
} else {
scoresResource.query(function (allScores) {
scoresData.length = 0;
angular.forEach(allScores, function (dataEntry) {
scoresData.push(dataEntry);
});
deferred.resolve(scoresData);
});
}
return deferred.promise;
},
getByLeagueName: function(leagueName) {
return this.getAll().then(function (allScores) {
return $filter('filter')(allScores, function (score) {
return score.League === leagueName;
})
})
}
}
});
我的控制器只需获取过滤后的数据并将其添加到范围内。
.controller('LivescoresCtrl', function ($scope, $stateParams, Leagues, Scores, $interval, Utils) {
Scores.getByLeagueName($stateParams.leagueName).then(function (scores) {
$scope.scores = scores;
});
})
但似乎在基础数据更新时,过滤后的数据不会自动更新。我想避免在视图中使用过滤器,因为有时我需要以我无法轻易实现的方式将数据组合在一起。
所以我想我的问题是为什么在主数据更新时这不会更新,这是角度世界中的有效方法。我可以针对数据的所有变体点击后端,但由于这是一个移动应用程序,并且应用程序中始终需要所有数据,因此我不想仅仅为了合并或过滤数据而提出额外请求。
谢谢,
答案 0 :(得分:0)
您只使用" getByLeagueName"返回的承诺,在控制器上设置一次数据。承诺只会解决一次!
我不确定ko.computed
到底是做什么的。但是,通过使用服务内部的过滤器,您在getByLeagueName
内部创建了一个新数组,该数组与原始数组无关。新阵列并不知道它来自哪里"!
您似乎正在尝试实施轮询更新,您应该在控制器内部而不是服务中执行此操作。将服务视为后端逻辑的容器,无需访问范围 - 这是控制器的用途。只要您不直接使用示波器,Angular就不会更新可见数据,因为这是Angular应用从中获取显示数据的唯一地方。
使用过滤数据的典型Angular方法是:在获取原始数据后,在控制器上提供原始数据。然后在视图(HTML)中使用过滤器,即:<div ng-repeat="entry in data | filter: someFilter">
。见ng-filter。这样Angular知道原始数据何时发生变化,再次对其运行过滤器,UI将毫不费力地更新。
如果你真的需要在视图以外的其他地方使用过滤后的数据 - 并确保你这样做 - 那么就有一些方法可以解决这个问题。一种是使用该服务通知控制器数据变化:通过$rootScope.$on
收听控制器内的事件,并通过$rootScope.$broadcast
在服务中发出该事件。
您还可以查看this repository,它采用基于承诺的方法来轮询数据,也许它适用于您的任务。