如何等待angularjs完成所有事情?

时间:2014-05-11 02:09:05

标签: angularjs initialization focus

this question类似,我希望无论何时添加,都要关注最后<select>。由于有一种方法可以做到这一点,我不需要任何指令,也没有手表和事件。我的功能

$scope.addNew = function() {
    $scope.items.push({});
    $timeout(function() {
        $("select").focus();
    });
};

工作得很好,除非直接从控制器函数定义中调用,如

angular.module('myModule').controller('MyCtrl', function($scope, $timeout) {
    $scope.items = {};
    ...
    $scope.addNew();
}

看起来超时发生在构造DOM并且$("select")为空之前。延迟大约100毫秒它再次起作用,但这是一个糟糕的黑客。

与在链接问题的答案中所说的相反,超时不够。

那么等待angularjs真正完成DOM和所有事情的可靠方法是什么?

更新

它可能不起作用,因为select被集中在指令中(包括ng-repeat和一些自己的指针)这就是为什么最初没有DOM元素的原因专注于。

根据评论,我需要一个指令。什么不清楚是如何做到的。我尝试并失败了,找到了一个更简单的解决方案。

我需要什么

我对此并不是很明确,所以让我澄清一下。

  • 我正在使用一个表,其中每行包含一些可编辑的字段。
  • addNew中,我想将重点放在新行的第一个可编辑字段上。
  • 就我而言,这恰好是最后一次选择。

除了最开始,当我从控制器主体添加第一行时,它才起作用。

为什么我反对使用指令

根据我的有限理解,它完全倒退了:

  • 指令修改给定元素的外观,行为或结构。但是没有应该修改的元素。我试图对从select本身到整个body
  • 的所有内容做出指示
  • 它需要watch某事或听一个事件,但我只想手动调用一个函数。
  • 它不起作用(对于我和其他人,因为对链接问题的评论显示)。

3 个答案:

答案 0 :(得分:2)

我将试图影响你在这里使用指令,只是为了执行这种行为 这是fiddle

基本前提是将行为指令添加到转发器内的元素:

<table>
     <tr ng-repeat="item in items">
         <td>{{item}}: <input type="text" auto-focus/></td>
     </tr>
</table>

然后你的指令将重点放在最后添加的元素上:

app.directive('autoFocus', function(){ 
    return function link(scope, elem){
        elem[0].focus();   
    }
});

除非我遗漏了您需要的东西,否则不需要观察者或活动。

答案 1 :(得分:1)

操纵DOM的代码应该在一个指令中,但是如果你切换到一个指令并且仍然有理由等到Angular完成更新范围和dom,请使用$ scope。$ evalAsync:

$scope.$evalAsync( function() { 
  // This will wait until Angular is done updating the scope
  // Do some stuff here
  //
});

答案 2 :(得分:1)

解决方案非常简单:我没有直接调用$scope.addNew();,而是将其放入$scope.init调用<form ng-init="init()">

根据documentation

  

ngInit的唯一合适用途是用于别名ngRepeat的特殊属性,如下面的演示所示。除了这种情况,您应该使用控制器而不是ngInit来初始化作用域上的值。

这似乎是错误的(或者可能不是,因为ngRepeat涉及)。我只是用它来推迟对$scope.addNew();的调用,其中timeout和发布事件均无效。