这个问题源于ng-grid的互动,但是我在其他几个地方踩到了我的脚趾。
与页面的交互提高了焦点在某个控件上的需要。
对于ng-grid,可能会单击标题中的过滤器按钮。这会导致弹出(但不是真正的模态对话框)输入控件出现然后需要焦点,因此用户不必再次单击以输入过滤器文本。我假设这应该在指令中完成,但是如何在这种情况发生时获得该指令?
另一个交互可能是在尝试保存表单之后。假设有一个验证不能在客户端发生(多用户应用程序,获取资源的竞争条件)。当从promise返回错误时,我想将光标放在需要更改的字段中。 )哪个字段取决于服务器的错误响应。)
我认为我真正想要的是相当于$('#id')。focus()接受ng-model并在页面上找到正确的控件并将光标放在该字段中,但是可以在完成承诺或对事件作出反应时使用。我意识到来自model =>的链接DOM是有问题的(模型可能出现在页面上的许多位置),但在表单输入的情况下,这可能不是真的,或者可能不是真的以促进这种应用程序响应。
我对于逻辑应该在哪里以及如何抓住包含它的对象有点迷失。
答案 0 :(得分:1)
这是一个类似的问题,有一些很好的答案。我认为第二个答案最接近你要求的答案
How to set focus on input field?
而不是绑定布尔值"应该集中注意力#34;字段,该指令使用事件将焦点设置在所需的元素上。
与您描述的$('#id')。focus()功能相比,此方法有几个优点。最大的一点是,通过事件方法,您的控制器可以在DOM之外进行模拟和测试,因为测试可以只查找触发事件,而不是检查哪个DOM元素具有焦点。
这是一个非常通用的示例,说明如何进行字段验证。感谢@blesh指令/服务实现
在表单中,您可以添加focus-on
指令。只需为每个字段使用唯一的事件名称:
<input type="text" name="name" focus-on="input-name" />
<input type="text" name="email" focus-on="input-email" />
在您的控制器中,进行现场验证后,您可以调用&#34;焦点&#34;使用您在模板中指定的focus-on="input-{name}"
值进行服务。这里我只是将input-
添加到字段名称中,但您可以使用任何您喜欢的命名约定。
app.controller('MyCtrl', function($scope, focus) {
$scope.validate = function() {
// ...
// Do your field validation
// ...
if (invalidFields.length) {
focus('input-' + invalidFields[0].name);
}
};
});
然后只需定义您的指令和服务
app.directive('focusOn', function() {
return function(scope, elem, attr) {
scope.$on('focusOn', function(e, name) {
if(name === attr.focusOn) {
elem[0].focus();
}
});
};
});
app.factory('focus', function ($rootScope, $timeout) {
return function(name) {
$timeout(function (){
$rootScope.$broadcast('focusOn', name);
});
}
});