AngularJS ngShow和焦点

时间:2014-07-10 14:07:02

标签: javascript jquery html css angularjs

根据textarea变量是否为真,尝试在Angular中显示preview。在preview设置为true后,我还想将焦点设置为textarea

控制器逻辑

.controller('MyCtrl', ['$scope', function ($scope) {
    $scope.preview = false;
    $scope.showPreview = function() {
        $scope.preview = true;
    }
}])

指令逻辑

.directive('previewFocus', function() {
    return function(scope, element, attrs) {
       scope.$watch('preview', 
         function (newValue) { 
            newValue && element[0].focus();
         },true);
      };    
});

然后我有一个div,点击它后会触发showPreview()方法:

<div ng-click="showPreview()">Add Post</div>

textarea指令的preview-focus

<textarea class="previewInput" preview-focus></textarea>

我调试了代码,所有内容都按预期执行,包括scope.$watch函数的回调。但是,textarea并没有成为焦点。如果我不使用ngShow指令,焦点可以正常工作。下面是两个显示两种情况的JSFiddle示例。

焦点不起作用JSFiddle with ngShow

焦点正常JSFiddle without ngShow

有没有人知道使用ngShow的好方法并同时关注显示的元素?

2 个答案:

答案 0 :(得分:3)

使用$ timeout:

.directive('previewFocus', function($timeout) {
    return function(scope, element, attrs) {
       scope.$watch('preview', 
         function (newValue) { 
            console.log('preview changed!')
            $timeout(function() {
                newValue && element[0].focus();
            }, 0, false);
         });
      };    
});

这是有效的,因为$ timeout将执行$ timeout内的代码推迟到渲染阶段之后(因此在执行ng-show的$ watch之后,当textarea变为可见时)

旁注:我删除了$ watch的第二个参数 - 对原始变量的$ watch不需要深度监视。

Demo Fiddle

答案 1 :(得分:1)

有点黑客,但是做了工作(JSFiddle):

function (newValue) { 
  window.setTimeout(function() {
    newValue && element[0].focus();
  }, 0);
},true);

当然在这种情况下,Angular的$ timeout是首选。