AngularJS:基础数据更改时未过滤的过滤数据

时间:2014-11-02 10:34:22

标签: javascript angularjs angularjs-service angular-promise

我是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;
    });
})

但似乎在基础数据更新时,过滤后的数据不会自动更新。我想避免在视图中使用过滤器,因为有时我需要以我无法轻易实现的方式将数据组合在一起。

所以我想我的问题是为什么在主数据更新时这不会更新,这是角度世界中的有效方法。我可以针对数据的所有变体点击后端,但由于这是一个移动应用程序,并且应用程序中始终需要所有数据,因此我不想仅仅为了合并或过滤数据而提出额外请求。

谢谢,

1 个答案:

答案 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,它采用基于承诺的方法来轮询数据,也许它适用于您的任务。