2015-04-02 37 views
0

我有一个简单的指令,绘制了一些元素,就像这个例子。我想以编程方式设置一些样式属性,但在链接功能中,元素显然还没有。如何在将DOM元素添加到我的指令时得到通知?

Here's a fiddle.

我认为正在发生的是,当我称之为colorSquares功能,没有广场尚未在DOM。将它包装在$超时中,它可以工作,但这只是感觉错误。

当元素存在时,我可以通知任何方式吗?或者是否有一个地方可以放置访问它们的代码,并保证在它们存在后运行?

myApp.directive('myDirective', ['$timeout', function ($timeout) { 
return { 
    restrict: 'E', 
    replace: false, 
    link: function (scope, elem, attr) { 

     scope.squares = [1,2,3,4,5]; 

     function colorSquares() { 
      var squaresFromDOM = document.getElementsByClassName('square'); 
      for (var i = 0; i < squaresFromDOM.length; i++) { 
       squaresFromDOM[i].style['background-color'] = '#44DD44'; 
      } 
     } 

     // this does not work, apparently because the squares are not in the DOM yet    
     colorSquares(); 

     // this works (usually). It always works if I give it a delay that is long enough.   
     //$timeout(colorSquares); 


    }, 
    template: '<div><div ng-repeat="s in squares" class="square"></div></div>' 
}; 

}]);

+0

我强烈推荐阅读[本文](http://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background)。它会让你的生活变得如此简单。 – Pete 2015-04-02 20:23:09

回答

0

你应该使用Angular而不是使用Angular,也就是说你应该使用数据绑定来做你正在做的事情而不是事件/通知。

http://jsfiddle.net/efdwob3v/5/

link: function (scope, elem, attr) { 
    scope.squares = [1,2,3,4,5]; 
    scope.style = {"background-color": "red"}; 
}, 
template: '<div><div ng-repeat="s in squares" class="square" ng-style="style"></div></div>' 

那说,有在做上述,只是使用具有红色背景色,甚至只是在做style="background-color: red;"

0

你把答案在你qeustion不同的类没有区别, “如果我给它足够长的延迟,它总是有效的。”

所以,只要使延迟足够长,在这种情况下可以通过添加一个onload事件来实现,因为当元素被添加到DOM时,它会调用该事件。

因此,而不只是colorSquares();你可以使用:

window.addEventListener("load", colorSquares); 

虽然这可能不是理想的解决方案,因为它也将触发,当别的东西触发onload事件。

0

直接回答你的问题。要知道一个元素是否被添加到指令或DOM中,您可以简单地在该元素上添加一个指令,因为指令只有在它所在的元素已经在DOM中时才会运行。

使用你的代码的一部分,作为一个例子:

myApp.directive('myDirective', function() { 
    return { 
     ...  
     //put custom directive that will notify when DOM is ready 
     template: '<div><div ng-repeat-ready ng-repeat="s in squares" class="square"></div></div>' 
    }; 
}); 

这里是习俗ng-repeat-ready指令:

myApp.directive('ngRepeatReady', function() { 
    return { 
     link: function (scope) { 
      if (scope.$last) { 
       //do notification stuff here 
       //for example $emit an event 
       scope.$emit('ng-repeat is ready'); 
      } 
     } 
    } 
}); 

这个指令时的元素是位于运行已经在DOM并检查该元素是否在范围上具有$last属性(ng-repeat为迭代对象的最后一个元素设置此标志),这意味着ng-repeat指令已完成,您现在可以对其进行操作DOM安全。

相关问题