如何将焦点设置为角度应用程序中的控件?

时间:2014-03-30 14:23:28

标签: angularjs

这个问题源于ng-grid的互动,但是我在其他几个地方踩到了我的脚趾。

与页面的交互提高了焦点在某个控件上的需要。

对于ng-grid,可能会单击标题中的过滤器按钮。这会导致弹出(但不是真正的模态对话框)输入控件出现然后需要焦点,因此用户不必再次单击以输入过滤器文本。我假设这应该在指令中完成,但是如何在这种情况发生时获得该指令?

另一个交互可能是在尝试保存表单之后。假设有一个验证不能在客户端发生(多用户应用程序,获取资源的竞争条件)。当从promise返回错误时,我想将光标放在需要更改的字段中。 )哪个字段取决于服务器的错误响应。)

我认为我真正想要的是相当于$('#id')。focus()接受ng-model并在页面上找到正确的控件并将光标放在该字段中,但是可以在完成承诺或对事件作出反应时使用。我意识到来自model =>的链接DOM是有问题的(模型可能出现在页面上的许多位置),但在表单输入的情况下,这可能不是真的,或者可能不是真的以促进这种应用程序响应。

我对于逻辑应该在哪里以及如何抓住包含它的对象有点迷失。

1 个答案:

答案 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);
    });
  }
});