AngularJS - 对服务中的数组进行排序,在控制器/视图中保留绑定

时间:2015-01-14 16:17:24

标签: javascript angularjs sorting firebase

我正在寻找一种方法来对Angular服务中的数组进行排序,并且仍然在控制器中保留正确的绑定。

如果我跳过排序,绑定工作得很好,但阵列没有按照我的需要进行排序。

每当我使用Lodash的_.sortBy或角色$filter('orderBy')服务执行排序时,会发生以下两种情况之一:

  1. 服务中的数组已正确排序,但由于不再引用相同的数组,因此与控制器的绑定被切断。

  2. 如果我尝试使用Lodash的_.cloneDeep或角度angular.copy解决此问题,浏览器会因循环引用(?)而冻结。

  3. Service.js

        angular.module('exampleapp')
    .factory('ClientFeedService', function($filter, $firebase, FIREBASE_URL, FeedItemService) {
    
      return function(clientId) {
    
        var ClientFeedService = this;
        var ref = new Firebase(FIREBASE_URL + 'feeds/clients/' + clientId);
        var initialDataLoaded = false;
        ClientFeedService.feedArray = [];
    
        ClientFeedService.sortItems = function() {
          // Sorting logic here
        };
    
    
        /**
         * Bind to the initial payload from Firebase
         */
        ref.once('value', function() {
    
          // Sort items after initial payload
          ClientFeedService.sortItems();
          initialDataLoaded = true;
        });
    
    
        /**
         * Bind to new items being added to Firebase
         */
        ref.on('child_added', function(feedItemSnap) {
          console.log('child_added');
          ClientFeedService.feedArray.unshift(FeedItemService.find(feedItemSnap.name(), feedItemSnap.val()));
    
          // Sort after new item if initial payload loaded
          if (initialDataLoaded) {
            ClientFeedService.sortItems();
          }
        });
    
        ClientFeedService.getFeedItems = function() {
          return ClientFeedService.feedArray;
        };
    
        return ClientFeedService;
      };
    
    });
    

    Controller.js

        app.controller('ClientsFeedCtrl', function($scope, $stateParams, ClientFeedService) {
    
      var clientId = $stateParams.clientId;
      $scope.clientFeed = new ClientFeedService(clientId).getFeedItems();
    
    });
    

2 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题。首先,让我们看看发生了什么。

您正在将初始数组分配给$scope.cliendFeed。在此之后,随着数据的添加,正在生成一个新数组并将其存储在服务中,但您仍然可以引用原始数组。最后,您要做的是找到一种方法让$scope.clientFeed与您的服务保持同步。

最简单的解决方案可能是使用getter方法,而不是在范围中存储对数组的引用。

为了做到这一点,你必须添加如下内容:

var service = new ClientFeedService(clientId);
$scope.getClientFeed = function () {
  return service.getFeedItems();
};

并确保您的ng-repeat调用此函数:

<li ng-repeat="item in getClientFeed()">...</li>

希望有所帮助!

答案 1 :(得分:0)

  1. 您可以将从API返回的新数据推送到控制器中的同一个数组,然后应用 $ filter
  2. 以下是示例

    function getData(){
       $scope.array.push(returnData);
       sortArrayList($scope.orderByField, $scope.reverseSort);
    }
    
    function sortArrayList(orderByField, reverseSort){
       $scope.array = $filter('orderBy')($scope.array, orderByField, reverseSort);
    }