Angular noobie在这里。 我想知道当范围中的值通过某种方式改变时,更改dom的最佳方法是什么。我读到将dom操作逻辑放在控制器中并且这是指令的工作并不好。
这是一个plunkr
http://plnkr.co/edit/xWk5UBwifbCF2raVvw81?p=preview
基本上,当通过单击上面的plunkr中的加载数据按钮更改数据时,我希望其值更改的单元格自动突出显示。我不能让它为我的生活工作。
任何帮助?
答案 0 :(得分:27)
我认为观察每个荧光笔的具体值而不是观看整个集合会更好。例如:
<td highlighter="person.firstName">{{ person.firstName }}</td>
这样,highlighter
- 指令可以非常简单,例如:
app.directive('highlighter', ['$timeout', function($timeout) {
return {
restrict: 'A',
scope: {
model: '=highlighter'
},
link: function(scope, element) {
scope.$watch('model', function (nv, ov) {
if (nv !== ov) {
// apply class
element.addClass('highlight');
// auto remove after some delay
$timeout(function () {
element.removeClass('highlight');
}, 1000);
}
});
}
};
}]);
尽管如此,为了实现这一目标,您必须告诉角度数据实际发生了变化。目前,对象标识的角度轨迹people
不是这种情况。在您覆盖它的那一刻,angular将删除所有相关的dom元素。为了适应这种情况,请使用:
ng-repeat="person in people track by $index"
将告诉angular将数组的索引视为标识。
答案 1 :(得分:6)
感谢您发布上述答案。我注意到,如果值经常变化,动画会闪烁,当另一个动画已经激活时,会触发超时。
如果已设置超时,我已通过重置超时来解决此问题。
另外,我添加了代码来检查值是增加还是减少,并设置不同的css类。
app.directive('newvalue', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.addClass('newvalue');
scope.$watch(attrs.newvalue, function (nv, ov) {
function settimeout() {
attrs.timeout = $timeout(function () {
element.removeClass('newvalue-up');
element.removeClass('newvalue-down');
attrs.timeout = null;
}, 1000);
}
if (nv !== ov) {
if(attrs.timeout) {
//newvalue already set.. reset timeout
$timeout.cancel(attrs.timeout);
settimeout();
} else {
if(nv > ov) {
element.addClass('newvalue-up');
} else {
element.addClass('newvalue-down');
}
settimeout();
}
}
});
}
};
}]);
答案 2 :(得分:3)
经过一番阅读后,我注意到考虑到性能,使用$watch
存在一些疑问。我找到了使用$observe
的其他解决方案。
好好阅读$watch
和$observe
:https://stackoverflow.com/a/14907826/2901207
的javascript:
var app = angular.module('angularjs-starter', []);
app.directive('highlightOnChange', function() {
return {
link : function(scope, element, attrs) {
attrs.$observe( 'highlightOnChange', function ( val ) {
console.log("Highlighting", val);
element.effect('highlight');
});
}
};
});
app.controller('myController', function($scope, $timeout) {
$scope.val = 1;
$scope.updateVal = function() {
$scope.val = $scope.val + 1;
};
});
HTML:
<body ng-controller="myController">
<div highlight-on-change="{{val}}">
Total: {{ val }}
</div>
<button ng-click="updateVal()">Add to Total</button>
</body>
原始来源:http://plnkr.co/edit/FFBhPIRuT0NA2DZhtoAD?p=preview 来自这篇文章:https://groups.google.com/d/msg/angular/xZptsb-NYc4/YH35m39Eo2wJ
更复杂的用法,对我来说非常合适,因为它会在更新到来时突出显示特定列。
<table class="table table-hover">
<tr>
<th ng-repeat="col in fc.tableColumns"><!--fc is a controller-->
{{col.displayName}}
</th>
</tr>
<tr ng-repeat="item in fc.items track by item.id">
<td highlight-on-change="{{value}}" ng-repeat="(key,value) in item">
@*{{key}} =*@ {{value}}
</td>
</tr>
</table>
正如我所说,更新特定列,同时在控制器中的某处执行此操作。
items[index] = item;//item from server