Подтвердить что ты не робот

Настройка фокуса на поле ввода после ng-show

Возможно ли установить фокус поля ввода через контроллер после загрузки данных (через $resource в этом случае)?

Ввод скрывается с помощью ng-show, пока данные не будут возвращены из API, но я не могу найти способ установить фокус на вход. Я знаю имя ng-модели ввода и имя ввода, что означает, что я мог бы сделать это через jQuery, но я предпочел бы сделать это, если возможно, способом AngularJS.

Я пробовал здесь множество примеров директив, но все они кажутся pre-1.2 ng-focus, полагайтесь на ng-click сначала с одной кнопки (не может быть в моем случае) т.
Любые советы очень благодарны.

4b9b3361

Ответ 1

Это простая директива, которая может работать для вас

<input focus-on="!!myResourceData" />

.directive('focusOn',function($timeout) {
    return {
        restrict : 'A',
        link : function($scope,$element,$attr) {
            $scope.$watch($attr.focusOn,function(_focusVal) {
                $timeout(function() {
                    _focusVal ? $element[0].focus() :
                        $element[0].blur();
                });
            });
        }
    }
})

Ответ 2

Я продлил ответ на работу с angular ng-show и ng-hide

app.directive('focusOnShow', function($timeout) {
    return {
        restrict: 'A',
        link: function($scope, $element, $attr) {
            if ($attr.ngShow){
                $scope.$watch($attr.ngShow, function(newValue){
                    if(newValue){
                        $timeout(function(){
                            $element[0].focus();
                        }, 0);
                    }
                })      
            }
            if ($attr.ngHide){
                $scope.$watch($attr.ngHide, function(newValue){
                    if(!newValue){
                        $timeout(function(){
                            $element[0].focus();
                        }, 0);
                    }
                })      
            }

        }
    };
})

Все, что вам нужно, это добавить атрибут focus-on-show

<input type="text" ng-show="editing" focus-on-show />

Ответ 3

Основываясь на ответе koolunix, если вы только хотите сфокусировать элементы ввода, также может оказаться полезным найти первый элемент ввода, который является дочерним элементом элемента с директивой focus-on.

Это полезно в случае внешней библиотеки, абстрагирующей элемент ввода с помощью директив и шаблонов.

.directive('focusOn', function ($timeout) {
    return {
        restrict: 'A',
        priority: -100,
        link: function ($scope, $element, $attr) {

            $scope.$watch($attr.focusOn,
                function (_focusVal) {
                    $timeout( function () {
                        var inputElement = $element.is('input')
                            ? $element
                            : $element.find('input');

                         _focusVal ? inputElement.focus()
                                   : inputElement.blur();
                    });
                }
            );

        }
    };
});

Ответ 4

Вы должны использовать тайм-аут в вашем контроллере, потому что он должен отображаться раньше, вот похожий пример с окном поиска, которое по умолчанию скрыто

HTML:

<input ng-show="vm.isActive" id="searchInputBox" ></input>
<input type="button" ng-click="vm.toggleActiveInactive();">

контроллер:

vm.isActive=false;
vm.toggleActiveInactive=toggleActiveInactive; // vm= viewmodel

function toggleActiveInactive() {
          if(vm.isActive==true){
            vm.isActive=false;
          }else{
            vm.isActive=true;

            $timeout(function(){     
              document.getElementById('searchBoxInput').focus()
            }, 10 );

          }
        }

Ответ 5

Другая версия этого для Angular.io

import {Directive, ElementRef, Input, OnChanges, SimpleChanges} from '@angular/core';

//Directive to that toggles focus from boolean value set with focusOn
@Directive({
  selector: '[focusOn]'
})
export class FocusOnDirective implements OnChanges {
  @Input('focusOn') setFocus: boolean;

  constructor(private hostElement: ElementRef) {}

  ngOnChanges(changes : SimpleChanges) {
    (!!changes.setFocus && !!changes.setFocus.currentValue) ?
      this.hostElement.nativeElement.focus() :
      this.hostElement.nativeElement.blur();
  }
}