AngularJS:尝试使用延迟数据进行过滤

时间:2014-09-14 08:56:51

标签: angularjs

我有这个HTML:

  <div ng-app='myApp'>
    <div ng-controller='testCtrl'>
      <h3>All possesions</h3>
      {{possessions}}
      <h3>Green cars</h3>
      {{greenishCars}}
    </div>
  </div>

这个脚本:

angular.module('myApp', [])
  .factory('getPossessionsService', ['$timeout',
    function($timeout) {
      var possessions = {};
      $timeout(function() {
        possessions.cars = [{
          model: "Mazda 6",
          color: "lime green"
        }, {
          model: "Audi A3",
          color: "red"
        }, {
          model: "Audi TT",
          color: "green"
        }, {
          model: "Volkswagen Lupo",
          color: "forest green"
        }];
        possessions.jewelry = [{
          type: "ring",
          metal: "gold"
        }, {
          type: "earring",
          metal: "silver"
        }];
      }, 1000);
      return possessions;
    }
  ])

.controller('testCtrl', ['$scope', 'filterFilter', 'getPossessionsService',
  function($scope, filterFilter, getPossessionsService) {
    $scope.possessions = getPossessionsService;

    $scope.greenishCars = filterFilter($scope.possessions.cars, carColorIsGreenShade);

    function carColorIsGreenShade(car) {
      return ['green', 'forest green', 'lime green'].indexOf(car.color) != -1;
    }
  }
]);

我试图让$ scope.greenishCars在数据可用时正确更新,但事实并非如此。我知道这是因为$ scope.possessions.cars是一个数组,因此不是对数据的引用,因此它不会更新。但是,如何更改我的脚本以便在数据到达时更新greenishCars?我猜我应该“直接”使用$ scope.possessions,但我不太明白我应该如何重写这个......

请参阅此plunk

编辑:关于选择哪个答案的想法 正如Oliver和MajoB的答案中的评论一样,我最终使用了过滤器和手表。在我的特殊情况下,对数据的请求是在另一个地方(不是在我的页面的控制器中)进行的,所以要对解决承诺采取行动并不是那么容易(有承诺。然后按照Oliver的建议)因此我用了一块手表。但手表有几点需要注意。如果要监视的变量不在作用域上,则必须通过从函数返回该变量来提供该变量。如果你想观察现有房产的变化(比如有人用不同的颜色重新塑造我现有的马自达6),那么所有的手表答案都无效,因为你需要在调用$ watch时添加“true”。当你将'true'作为第二个参数添加到$ watch时,它会监视变量实际值的变化,并且还会检查对象/数组中的深层值(不需要检查引用,请参阅{ {3}})。我最终得到了这个控制器/ $ watch用于我现实生活中的用例(这与我上面的例子略有不同,并且基于Olivers this blog),它看起来像这样(改为适合插件):

.controller('testCtrl', ['$scope', 'greenFilter', 'getPossessionsService',
  function($scope, greenFilter, getPossessionsService) {
    var none-scope-possessions = getPossessionsService; // I do not want to expose all properties on the scope....
    $scope.greenishCars = [];

    $scope.$watch(function() {return none-scope-possessions.cars}, function(newValue){
      if (newValue) {
        $scope.greenishCars = greenFilter(newValue);
      }
    },true);
  }
]);

4 个答案:

答案 0 :(得分:2)

您可以观看数据更改:

$scope.$watch('possessions.cars', function(){
    $scope.greenishCars = filterFilter($scope.possessions.cars, carColorIsGreenShade);
});

答案 1 :(得分:1)

您可以观看possesions集合的变化:

$scope.$watchCollection('possessions', function (newValue) {

  if (newValue)
  {
    $scope.greenishCars = filterFilter(newValue.cars, carColorIsGreenShade);
  }
});
  

http://plnkr.co/edit/Sl6dW0pqKr593OXrgDb9?p=preview

答案 2 :(得分:1)

我建议您只建立自己的自定义过滤器:

.filter('green', function() {
  return function(possessions) {
    if (!possessions) return null;

    var filtered = [];
    angular.forEach(possessions, function(possesion){
      if (['green', 'forest green', 'lime green'].indexOf(possesion.color) != -1) {
        filtered.push(possesion);
      }
    });
    return filtered;
  };
})

然后通过该过滤器传递您的集合,如下所示:

<div ng-controller='testCtrl'>
  <h3>All possesions</h3>
  {{possessions}}
  <h3>Green cars</h3>
  {{possessions.cars|green}}
</div>

其他一切都会自动发生。请参阅updated plunkr

答案 3 :(得分:0)

首先,var possessions = {};你宣布了​​一个物体,汽车是这个物体中的一个场,它有一系列汽车。所以要么返回所有来自caars,要么在标记中通过possessions.cars [0]调用它。如果你只想调用一个值..或者如果要显示所有值,则使用ng-repeat =&#34;汽车in possessions.cars&#34;