实现具有所有实例的共享计时器的指令的最佳“Angular Way”是什么?
例如,我有一个指令“myComponent”,并且在页面上出现了很多次。 在组件内部,存在一些以一定间隔闪烁的文本。
由于业务需求和性能方面的考虑,我希望单个“超时”能够立即切换所有实例的闪烁(在文档准备好之后)。
我考虑过在指令定义中编写一些代码:
//Pseudo code
angular.module("app",[]).directive("myComponent", function($timeout){
$(function() { $timeout(function(){ $(".blink").toggle(); }, 3000); } );
return {
//Directive definition
};
});
或者使用某种服务来接收$element
并向其添加删除类:
//Pseudo code
angular.module("app",[])
.service("myService", function($timeout){
var elements = [];
this.addForBlink = function(element) { elements.push(element) };
$(function() { $timeout(function(){ $(elements).toggle(); }, 3000); } );
})
.directive("myComponent", function(myService){
return {
compile:function($element){
myService.addForBlink($element);
return function() {
//link function
}
}
};
});
答案 0 :(得分:2)
在我看来,最优雅和高效的方法是通过在指令初始化函数中指定指令的逻辑来组合这两种方法。这是我实际意思的脚手架:
app.directive('blinking', function($timeout){
var blinkingElements = [];
var showAll = function() {
for(var i = 0; i < blinkingElements.length; i++){
blinkingElements[i].addClass("blinking");
}
};
var hideAll = function() {
for(var i = 0; i < blinkingElements.length; i++){
blinkingElements[i].removeClass("blinking");
}
};
var blink = function () {
$timeout(showAll, 500);
$timeout(function(){
hideAll();
if (blinkingElements.length > 0) {
blink();
}
}, 1000);
};
return {
link : function(scope, element, attrs){
blinkingElements.push(element);
if (blinkingElements.length == 1) {
blink();
}
element.on("$destroy", function(){
var index = blinkingElements.indexOf(element);
blinkingElements.splice(index, 1);
});
}
}
});
这是工作 demo 。
此外,您可以注入一些将负责配置的service
(设置间隔和/或类),或者您可以通过将对象直接传递给属性来提供配置。在后一种情况下,您可以为不同的元素启用不同的类,但是当间隔设置多次时,您应该考虑一些策略如何处理情境。