使用动态生成的id处理DOM元素

时间:2018-04-24 07:40:29

标签: angularjs

我有一个简单的Angularjs应用程序,其控制器包含一个名为id的字符串作用域列表:

angular.module('app', [])
.controller('appCtrl', ['$scope', '$timeout',
  function($scope, $timeout) {
    $scope.ids = ['id1', 'id2'];
  }]); 

在html partial中,ngrepeat迭代id并将此id添加到div列表中:

<div ng-app="app">
<div ng-controller="appCtrl">

<div ng-repeat="id in ids" ng-attr-id="{{id}}">
  div-{{id}}
  </div>

  </div>
</div>

只有当它包含在$ timeout中时,才能在控制器中使用angular.element选择这些div:

$timeout(function(){
 console.log('with timeout, element found');
 console.log(angular.element('#'+$scope.ids[0]));
});

console.log('no timeout, element not found');
console.log(angular.element('#'+$scope.ids[0]));

以下是一个工作示例:https://codepen.io/neptune01/pen/zjqGzO

究竟是什么导致了这种异步流程?为什么我需要超时来选择元素?

我试图在可能的情况下摆脱超时。有没有更好的方法来进行元素选择,最终没有超时?

2 个答案:

答案 0 :(得分:2)

正如我所听到的那样,AngularJs存在问题。控制器编码,在DOM完成之前执行,因此在没有$timeout的情况下,没有要选择的标识'#'+$scope.ids[0]。您必须使用$timeout来选择和使用它。

有关更多信息,请搜索并阅读digest cycle of angularjs

答案 1 :(得分:1)

@ Saeed.At已指出正确的方向。

它与AngularJS摘要周期有关。 ng-repeat,ng-include和其他几个指令以及它们的渲染在下面的摘要周期中排队并呈现。例如,

  • 控制器&amp;模板渲染
  • ng-repeat rendering

现在你已经看到尝试在开始时直接访问ng-repeat项目不会起作用,因为它们只会在一个周期后再渲染。

$ timeout基本上是一样的。如果您没有提供超时参数,它将在下一个摘要周期后排队。因此链条看起来像这样

  • 控制器&amp;模板渲染
  • ng-repeat rendering
  • $ timeout function

同样重要的是要注意,如果你的ng-repeat包含其他ng-includes或某些指令,他们也会自行排队,所以可能是单个$ timeout不够。对于这种情况,您必须采取不同的方法