我试图使用一个监视自定义属性内部更改的指令,该属性位于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 :(得分: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);