ng-repeat

时间:2016-11-24 13:28:44

标签: javascript angularjs

我试图使用一个监视自定义属性内部更改的指令,该属性位于ng-repeat循环中。 ng-repeat中使用的数组每5秒更新一次。当项目从之前的值更改时,我想为div设置动画。

我使用$watch来跟踪旧值和新值,但它们始终相同。我知道$watch函数永远不会检测范围的变化,因为只要数据加载就会再次触发ng-repeat。

目标是在值改变时为div的背景颜色设置动画。

但我怎么能避免这个?

指令:

.directive('animateOnChange', function($timeout) {
 return function(scope, element, attr) {
  scope.$watch(attr.animateOnChange, function(nv,ov) {
   if (nv!=ov) {
    if(attr.change > 0){
      element.addClass('changed-positive');
       $timeout(function() {
         element.removeClass('changed-positive');
       }, 1000);
    }else if (attr.change < 0){
      element.addClass('changed-negative');
       $timeout(function() {
        element.removeClass('changed-negative');
       }, 1000);
    }
  }
 });
};
});

HTML:

<div class="row" ng-repeat="item in data">
  <div class="box" animate-on-change="item.activeprice[0]" change="{{item.change[0]}}">
    <h2>{{item.desc[0]}}</h2>
    <p>Time: {{item.asktime[0]}}</p>
  </div>
</div>

$scope.data正在通过http请求进行调用/更新。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我建议将$ watch函数移动到父作用域。

$scope.$watch('data', function(newVal, oldVal) {
    if (newVal !== oldVal) {
        // You know something is different.
        //  1. Find items that are different with loop, forEach, etc.
        //  2. Create changedPositiveItems and changedNegativeItems arrays
        //     with ids of changed items
    }
}, true);

div的内部重复重复中你会有这样的事情。

<div animate-on-change 
     changed-positive="changedPositiveItems"
     changed-negative="changedNegativeItems"
     ng-class={'changed-positive-class': itemChangedPositive,
               'changed-negative-class': itemChangedNegative }>
     // content of item here
</div>

内部指令

$scope.itemChangedPositive = $scope.changedPositive.indexOf(item.id) > -1;
$scope.itemChangedNegative = $scope.changedPositive.indexOf(item.id) > -1;

我可能会遗漏您的数据细节,但我希望我能指出您的想法。我们在外部范围进行比较,并跟踪已经改变的内容,我们将其传递给子范围,我们可以检查该特定项目是否已更改。

另外,请注意,$scope.$watch第二个参数true意味着如果您拥有大量数据集,则深度观看对象可能会很昂贵。一种解决方法可能是将数据序列化并将其作为字符串进行比较,如果字符串不同,则只执行昂贵的比较操作。

答案 1 :(得分:0)

我最终在主控制器中使用$watch功能来监控变化并根据它创建动画。我在ng-repeat循环中的每一行都给出了一个基于`$ index的类。

<div class="box box-{{$index}}" ng-style="item.change[0] < 0 && { 'color' :'#c0392b' } || item.change[0] >= 0 && { 'color' :'#2980b9' } ">
    <h2>{{item.desc[0]}}</h2>
    <p>Time: {{item.asktime[0]}}</p>
</div>

控制器:

$scope.$watch('data', function(newVal, oldVal) {
     $timeout(function() {
      if (newVal !== oldVal) {
        for (var i = 0; i < newVal.length; i++) {
          for (var c = 0; c < oldVal.length; c++) {
            if(newVal[i].desc[0] == oldVal[c].desc[0]){
                if(newVal[i].activeprice[0] !== oldVal[c].activeprice[0]){
               if(newVal[i].change[0] > 0){
                $( ".box-" + i ).addClass('changed-positive');
                $timeout(function() {
                  $( ".box-" + i ).removeClass('changed-positive');
                }, 10);
              } else if(newVal[i].change[0] < 0){
                 $( ".box-" + i ).addClass('changed-negative');
                $timeout(function() {
                  $( ".box-" + i ).removeClass('changed-negative');
                }, 10);
              }
              }
            }
          }
        }
      }
    }, 300);
  }, true);