2016-11-24 50 views
0

我试图使用一个指令来监视位于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请求更新。

有什么建议吗?

回答

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); 
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); 

在ng-repeat 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意味着深入观察对象可能是昂贵的,如果你有大数据集。一种解决方法可能是序列化数据并将其作为字符串进行比较,如果字符串不同,则只需执行昂贵的比较操作。

+0

感谢。我将'$ watch'函数移到了父范围,并创建了一些循环来查找和动画变化的div。 – TietjeDK

相关问题