我有一个名为“connection”的指令,它给出了div的id之外的两个其他div之间的连接线。 id通过一些范围数据间接传递。
我的“连接”指令需要获取命名DOM元素的边界矩形,以便它可以在它们之间用适当的坐标绘制连接线。
在我的指令的link函数中,为这些id调用getElementById()
会返回undefined。这是因为在DOM中,当运行我的连接指令的链接函数时,这些元素的id仍然是id="intf-{{intf.id}}
“的形式(即,它们尚未被插值)。
有问题的div是使用ng-repeat生成的,并且动态分配了它们。
如何使我的指令有效地等待元素id进行插值,然后立即通知我的指令,以便它可以更新其模板和/或范围数据?
或者,我可以强制插值立即发生,以便getElementById()
可以工作,然后继续我的链接功能吗?
我已经看到你可以使用attrs.$observe()
来了解你自己的attr何时更新了,但我看不出如何使用任意元素的attrs来做到这一点。实际上,在插入名称之前,我甚至无法获取元素,因为这是我能识别它的唯一方法。
作为一个不完整的解决方案,以前开发此代码的开发人员添加了类似的内容:
link: function( scope, element, attrs ) {
var deferUntilElementsExist = function( newVal, oldVal, cb ){
var sourceElement = document.getElementById(scope.connection.source().id);
var targetElement = document.getElementById(scope.connection.target().id);
if( !sourceElement || !targetElement ) {
$timeout( function(){ deferUntilElementsExist( newVal, oldVal, cb ); }, 0 );
return;
}
updatePath();
if (cb) {
cb( newVal, oldVal );
}
};
这种工作,但线条看起来非常缓慢,就像每秒5个左右,即使有数百个,就好像它每个更新周期处理一行或类似的东西。
感谢。
答案 0 :(得分:1)
来自@pixelbits的评论让我朝着正确的方向前进。将第三个参数添加到$ timeout()设置为false,这会在每次调用后阻止$ apply(),使得" Incomplete Solution"工作得快得多。
link: function( scope, element, attrs ) {
var deferUntilElementsExist = function( newVal, oldVal, cb ){
var sourceElement = document.getElementById(scope.connection.source().id);
var targetElement = document.getElementById(scope.connection.target().id);
if( !sourceElement || !targetElement ) {
$timeout( function(){ deferUntilElementsExist( newVal, oldVal, cb ); },
0, false ); // Added third parameter here set to false
return;
}
updatePath();
if (cb) {
cb( newVal, oldVal );
}
};