2014-03-30 45 views
1

这个问题来源于ng-grid交互,但我在其他几个地方将脚趾绊了一下。如何将焦点设置为角度应用程序中的控件?

与页面的交互引发了对焦点进行某种控制的需求。

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

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

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

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

+1

可能重复[如何将焦点设置在AngularJS?](http://stackoverflow.com/questions/14833326/how-to-set -focus-in-angularjs) – msarchet

+0

我同意。我不明白为什么在我写这个问题的时候,SO中的自动提示没有提示。这个特定的问题适用于自动对焦,这不是,但解决方案应该适用于两者。 – boatcoder

回答

1

还有一个类似的问题,有一些很好的答案。我觉得第二个答案最接近你问什么

How to set focus on input field?

而是结合一个布尔“应侧重”字段,该指令使用事件将焦点设置所需的元素。

这种方法对于您描述的$('#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" /> 

在你的控制器,你做实地验证后,就可以调用使用您在模板中指定的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); 
    }); 
    } 
}); 
相关问题