与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
某事或听一个事件,但我只想手动调用一个函数。答案 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()">
。
ngInit的唯一合适用途是用于别名ngRepeat的特殊属性,如下面的演示所示。除了这种情况,您应该使用控制器而不是ngInit来初始化作用域上的值。
这似乎是错误的(或者可能不是,因为ngRepeat
涉及)。我只是用它来推迟对$scope.addNew();
的调用,其中timeout
和发布事件均无效。