Как установить фокус на поле ввода?

Что такое способ Angular, чтобы установить фокус на поле ввода в AngularJS?

Более конкретные требования:

  • Когда открывается Modal, установите фокус на предопределенный <input> внутри этого модального файла.
  • Каждый раз <input> становится видимым (например, нажатием кнопки), установите фокус на нем.

Я попытался выполнить первое требование с помощью autofocus, но это работает только тогда, когда модаль открывается впервые и только в некоторых браузерах (например, в Firefox это не работает).

Любая помощь будет оценена.

721
задан Misha Moroshko 12 февр. '13 в 16:08
источник поделиться
34 ответов
  • 1
  • 2
  • Когда модальный режим открыт, установите фокус на предопределенный <input> внутри этого модального файла.

Определите директиву и получите $watch свойство /trigger, чтобы он знал, когда нужно сфокусировать элемент:

Name: <input type="text" focus-me="shouldBeOpen">

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

Plunker

Тайм-аут $, кажется, необходим, чтобы дать модальное время для рендеринга.

'2'. Everytime <input> становится видимым (например, нажатием какой-либо кнопки), установите фокус на него.

Создайте директиву, по существу подобную той, что указана выше. Посмотрите на свойство scope, и когда оно станет истинным (установите его в обработчике ng-click), выполните element[0].focus(). В зависимости от вашего варианта использования вам может понадобиться или не понадобиться $timeout для этого:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.focusMe, function(value) {
        if(value === true) { 
          console.log('value=',value);
          //$timeout(function() {
            element[0].focus();
            scope[attrs.focusMe] = false;
          //});
        }
      });
    }
  };
});

Plunker


Обновление 7/2013. Я видел, как некоторые люди используют мои исходные директивы выделения, а затем имеют проблемы со встроенными полями ввода (т.е. поле ввода в модальном). Директива, не имеющая новых возможностей (или, возможно, новый охват ребенка), должна облегчить боль. Поэтому выше я обновил ответ, чтобы не использовать области выделения. Ниже приведен оригинальный ответ:

Оригинальный ответ для 1., используя область выделения:

Name: <input type="text" focus-me="{{shouldBeOpen}}">

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '@focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === "true") { 
          $timeout(function() {
            element[0].focus(); 
          });
        }
      });
    }
  };
});

Plunker.

Оригинальный ответ для 2., используя область выделения:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

Plunker.

Поскольку нам нужно reset свойство trigger/focusInput в директиве, '=' используется для двусторонней привязки данных. В первой директиве "@" было достаточно. Также обратите внимание, что при использовании "@" мы сравниваем значение триггера с "истинным", так как @всегда выводит строку.

557
ответ дан Mark Rajcok 12 февр. '13 в 19:23
источник поделиться

(EDIT: я добавил обновленное решение ниже этого объяснения)

Марк Райкок - человек... и его ответ - правильный ответ, но у него есть дефект (извините Марк)...

... Попробуйте использовать логическое значение, чтобы сфокусироваться на входе, затем размывайте вход, затем попробуйте использовать его, чтобы снова сфокусировать вход. Это не сработает, если вы не reset с логическим значением false, затем $digest, а затем reset вернемся к true. Даже если вы используете сравнение строк в своем выражении, вам придется изменить строку на что-то еще, $digest, а затем изменить ее. (Это было обработано обработчиком размытия).

Поэтому я предлагаю это альтернативное решение:

Использовать событие, забытую функцию Angular.

JavaScript любит события в конце концов. События по своей сути слабо связаны, и даже лучше, вы избегаете добавлять еще $watch к вашему $digest.

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e) {
          elem[0].focus();
      });
   };
});

Итак, теперь вы можете использовать его следующим образом:

<input type="text" focus-on="newItemAdded" />

а затем в любом месте вашего приложения...

$scope.addNewItem = function () {
    /* stuff here to add a new item... */

    $scope.$broadcast('newItemAdded');
};

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

Во всяком случае, этот тип вещей кричит "событие, вызванное" мне. Я думаю, что в качестве разработчиков Angular мы стараемся очень тяжело забивать привязанные к форме области привязки в дыры формы событий.

Это лучшее решение? Не знаю. Это решение.


Обновленное решение

После комментария @ShimonRachlenko ниже я изменил свой способ сделать это немного. Теперь я использую комбинацию сервиса и директивы, которая обрабатывает событие "за кадром":

Кроме того, это тот же самый принцип, о котором говорилось выше.

Вот демонстрационный демонстрационный план

Использование

<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
    focus('focusMe');
});

Источник

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);
    });
  }
});
256
ответ дан Ben Lesh 18 авг. '13 в 6:30
источник поделиться

Я нашел некоторые другие ответы слишком сложными, когда все, что вам действительно нужно, это

app.directive('autoFocus', function($timeout) {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            $timeout(function(){
                _element[0].focus();
            }, 0);
        }
    };
});

используется

<input name="theInput" auto-focus>

Мы используем таймаут, чтобы позволить вещам в dom render, даже несмотря на то, что он равен нулю, он, по крайней мере, ждет этого - таким образом, это работает в модалах и еще что-то еще

233
ответ дан ecancil 01 янв. '14 в 5:25
источник поделиться

HTML имеет атрибут autofocus.

<input type="text" name="fname" autofocus>

http://www.w3schools.com/tags/att_input_autofocus.asp

86
ответ дан Rayron Victor 29 сент. '15 в 15:43
источник поделиться

Вы также можете использовать функцию jqlite, встроенную в angular.

angular.element('.selector').trigger('focus');

58
ответ дан JordanC 11 дек. '13 в 11:35
источник поделиться

Это хорошо работает и angular способ фокусировки управления вводом

angular.element('#elementId').focus()

Это хотя и не чистый angular способ выполнения задачи, но синтаксис следует за стилем angular. JQuery играет роль косвенно и напрямую обращается к DOM, используя angular (jQLite = > JQuery Light).

При необходимости этот код можно легко поместить в простую директиву angular, где элемент доступен непосредственно.

51
ответ дан Sanjeev Singh 11 авг. '14 в 10:10
источник поделиться

Я не думаю, что $timeout - это хороший способ сфокусировать элемент на создании. Вот метод с использованием встроенной функции angular, выкопанной из мрачной глубины документов angular. Обратите внимание, как атрибут "link" можно разделить на "pre" и "post", для функций предварительной ссылки и пост-ссылки.

Рабочий пример: http://plnkr.co/edit/Fj59GB

// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
    return {
        link: {
            pre: function preLink(scope, element, attr) {
                console.debug('prelink called');
                // this fails since the element hasn't rendered
                //element[0].focus();
            },
            post: function postLink(scope, element, attr) {
                console.debug('postlink called');
                // this succeeds since the element has been rendered
                element[0].focus();
            }
        }
    }
});
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />

Документация по полной системе AngularJS: https://docs.angularjs.org/api/ng/service/$compile

30
ответ дан Cody Moniz 28 мая '14 в 22:07
источник поделиться

Вот мое оригинальное решение:

plunker

var app = angular.module('plunker', []);
app.directive('autoFocus', function($timeout) {
    return {
        link: function (scope, element, attrs) {
            attrs.$observe("autoFocus", function(newValue){
                if (newValue === "true")
                    $timeout(function(){element[0].focus()});
            });
        }
    };
});

И HTML:

<button ng-click="isVisible = !isVisible">Toggle input</button>
<input ng-show="isVisible" auto-focus="{{ isVisible }}" value="auto-focus on" />

Что он делает:

Он фокусирует ввод, когда он становится видимым с помощью ng-show. Здесь нет использования $watch или $.

17
ответ дан Edhowler 11 июня '14 в 23:58
источник поделиться

Я недавно написал директиву о двухстороннем связывании фокуса, как и модель.

Вы можете использовать директиву focus следующим образом:

<input focus="someFocusVariable">

Если вы someFocusVariable переменной сферы true в любом месте вашего контроллера, вход сфокусироваться. И если вы хотите "размыть" свой ввод, тогда для someFocusVariable можно установить значение false. Это похоже на первый ответ Марка Райкока, но с двусторонним связыванием.

Вот директива:

function Ctrl($scope) {
  $scope.model = "ahaha"
  $scope.someFocusVariable = true; // If you want to focus initially, set this to true. Else you don't need to define this at all.
}

angular.module('experiement', [])
  .directive('focus', function($timeout, $parse) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
          scope.$watch(attrs.focus, function(newValue, oldValue) {
              if (newValue) { element[0].focus(); }
          });
          element.bind("blur", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=false"); 
              }, 0);
          });
          element.bind("focus", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=true");
              }, 0);
          })
      }
    }
  });

Использование:

<div ng-app="experiement">
  <div ng-controller="Ctrl">
    An Input: <input ng-model="model" focus="someFocusVariable">
    <hr>
        <div ng-click="someFocusVariable=true">Focus!</div>  
        <pre>someFocusVariable: {{ someFocusVariable }}</pre>
        <pre>content: {{ model }}</pre>
  </div>
</div>

Вот скрипка:

http://fiddle.jshell.net/ubenzer/9FSL4/8/

17
ответ дан Umut Benzer 19 июля '13 в 9:49
источник поделиться

Для тех, кто использует Angular с плагином Bootstrap:

http://angular-ui.github.io/bootstrap/#/modal

Вы можете подключиться к обещанию opened модального экземпляра:

modalInstance.opened.then(function() {
        $timeout(function() {
            angular.element('#title_input').trigger('focus');
        });
    });

modalInstance.result.then(function ( etc...
10
ответ дан BPH 03 марта '15 в 18:32
источник поделиться

Мне было полезно использовать общее выражение. Таким образом, вы можете делать такие вещи, как автоматическое перемещение фокуса, когда текст ввода действителен.

<button type="button" moo-focus-expression="form.phone.$valid">

Или автоматически сфокусируйтесь, когда пользователь завершит поле с фиксированной длиной

<button type="submit" moo-focus-expression="smsconfirm.length == 6">

И, конечно, фокус после загрузки

<input type="text" moo-focus-expression="true">

Код для директивы:

.directive('mooFocusExpression', function ($timeout) {
    return {
        restrict: 'A',
        link: {
            post: function postLink(scope, element, attrs) {
                scope.$watch(attrs.mooFocusExpression, function (value) {

                    if (attrs.mooFocusExpression) {
                        if (scope.$eval(attrs.mooFocusExpression)) {
                            $timeout(function () {
                                element[0].focus();
                            }, 100); //need some delay to work with ng-disabled
                        }
                    }
                });
            }
        }
    };
});
7
ответ дан winry 30 апр. '15 в 12:15
источник поделиться

Не воскрешать зомби или подключить мою собственную директиву (хорошо, что именно я делаю):

https://github.com/hiebj/ng-focus-if

http://plnkr.co/edit/MJS3zRk079Mu72o5A9l6?p=preview

<input focus-if />

(function() {
    'use strict';
    angular
        .module('focus-if', [])
        .directive('focusIf', focusIf);

    function focusIf($timeout) {
        function link($scope, $element, $attrs) {
            var dom = $element[0];
            if ($attrs.focusIf) {
                $scope.$watch($attrs.focusIf, focus);
            } else {
                focus(true);
            }
            function focus(condition) {
                if (condition) {
                    $timeout(function() {
                        dom.focus();
                    }, $scope.$eval($attrs.focusDelay) || 0);
                }
            }
        }
        return {
            restrict: 'A',
            link: link
        };
    }
})();
7
ответ дан Jon Hieb 23 февр. '15 в 3:12
источник поделиться

Вместо создания собственной директивы можно просто использовать функции javascript для достижения фокуса.

Вот пример.

В html файле:

<input type="text" id="myInputId" />

В файле javascript, например, в контроллере, где вы хотите активировать фокус:

document.getElementById("myInputId").focus();
7
ответ дан user3657103 20 июня '14 в 17:56
источник поделиться

Во-первых, официальный способ сделать акцент сделан на дорожной карте для 1.1. Тем временем вы можете написать директиву, чтобы реализовать настройку фокуса.

Во-вторых, для установки фокуса на элемент после того, как он стал видимым, в настоящее время требуется обходное решение. Просто задержите вызов фокуса элемента() с помощью $timeout.

Поскольку тот же самый контроллер изменяет -DOM-проблему для фокуса, размытия и выбора, я предлагаю иметь директиву ng-target:

<input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget">
<button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>

Angular здесь: http://goo.gl/ipsx4, и более подробная информация приведена здесь: http://goo.gl/4rdZa

Следующая директива создаст функцию .focus() внутри вашего контроллера, как указано вашим атрибутом ng-target. (Он создает также .blur() и .select().) Демо: http://jsfiddle.net/bseib/WUcQX/

6
ответ дан broc.seib 13 февр. '13 в 10:26
источник поделиться

Если вам просто нужен простой фокус, который контролируется ng-click.

Html:

<input ut-focus="focusTigger">

<button ng-click="focusTrigger=!focusTrigger" ng-init="focusTrigger=false"></button>

Директива

'use strict'

angular.module('focus',['ng'])
.directive('utFocus',function($timeout){
    return {
        link:function(scope,elem,attr){
            var focusTarget = attr['utFocus'];
            scope.$watch(focusTarget,function(value){
                $timeout(function(){
                    elem[0].focus();
                });
            });
        }
    }
});
4
ответ дан TOBlender 17 февр. '14 в 21:06
источник поделиться

Простой, который хорошо работает с модалами:

.directive('focusMeNow', ['$timeout', function ($timeout)
{
    return {
        restrict: 'A',

        link: function (scope, element, attrs)
        {


            $timeout(function ()
            {
                element[0].focus();
            });



        }
    };
}])

Пример

<input ng-model="your.value" focus-me-now />
4
ответ дан Shawn Dotey 13 янв. '16 в 18:35
источник поделиться

У Марка и Блеста есть отличные ответы; однако у Марка есть недостаток, который указывает Блеш (помимо того, что он сложный для реализации), и я чувствую, что ответ Blesh имеет семантическую ошибку при создании службы, которая специально посылает запрос фокуса интерфейсу, когда действительно все, что ему нужно, - это способ задерживайте событие до тех пор, пока не будут прослушиваться все директивы.

Итак, вот что я в итоге сделал, который много крал от ответа Blesh, но сохраняет семантику события контроллера и отдельную службу "после загрузки".

Это позволяет легко подключаться к событию контроллера для других целей, кроме как просто фокусировки определенного элемента, а также позволяет налагать накладные расходы на функциональность "после загрузки", только если это необходимо, что может быть не во многих случаях.

Использование

<input type="text" focus-on="controllerEvent"/>
app.controller('MyCtrl', function($scope, afterLoad) {
  function notifyControllerEvent() {
      $scope.$broadcast('controllerEvent');
  }

  afterLoad(notifyControllerEvent);
});

Источник

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e, name) {
        elem[0].focus();
      });
   };
});

app.factory('afterLoad', function ($rootScope, $timeout) {
  return function(func) {
    $timeout(func);
  }
});
3
ответ дан joshperry 19 февр. '14 в 2:14
источник поделиться

Это также можно использовать ngModelController. Работа с 1.6+ (не знаю со старыми версиями).

HTML

<form name="myForm">
    <input type="text" name="myText" ng-model="myText">
</form>

JS

$scope.myForm.myText.$$element.focus();

-

N.B.: В зависимости от контекста вам, возможно, придется перевернуть функцию тайм-аута.

N.B.²: При использовании controllerAs это почти то же самое. Просто замените name="myForm" на name="vm.myForm" и в JS, vm.myForm.myText.$$element.focus();.

3
ответ дан Ludovic Guillaume 21 февр. '17 в 16:59
источник поделиться

Вы можете просто создать директиву, которая заставляет фокус на украшенный элемент на postLinking:

angular.module('directives')
.directive('autoFocus', function() {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            _element[0].focus();
        }
    };
});

Затем в вашем html:

<input type="text" name="first" auto-focus/> <!-- this will get the focus -->
<input type="text" name="second"/>

Это будет работать для модалов и ng-if toggled элементов, а не для ng-show, поскольку postLinking происходит только при обработке HTML.

3
ответ дан ibaixas 26 дек. '13 в 19:25
источник поделиться

Возможно, самое простое решение в эпоху ES6.

Добавление следующей директивы liner делает атрибут "автофокусировки" HTML эффективным на Angular.js.

.directive('autofocus', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())}))

Теперь вы можете просто использовать синтаксис автофокуса HTML5, например:

<input type="text" autofocus>
3
ответ дан Tsuneo Yoshioka 15 июня '17 в 10:58
источник поделиться

Просто новичок здесь, но я не мог заставить его работать в ui.bootstrap.modal с этой директивой:

directives.directive('focus', function($timeout) {
    return {
        link : function(scope, element) {
            scope.$watch('idToFocus', function(value) {
                if (value === element[0].id) {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});

а в методе $modal.open я использовал следующее выражение, чтобы указать элемент, в который нужно поместить фокус:

var d = $modal.open({
        controller : function($scope, $modalInstance) {
            ...
            $scope.idToFocus = "cancelaAteste";
    }
        ...
    });

на шаблоне у меня есть это:

<input id="myInputId" focus />
2
ответ дан pitervergara 14 февр. '14 в 15:57
источник поделиться

Если вы используете modalInstance и имеете объект, вы можете использовать "then" для выполнения действий после открытия модального. Если вы не используете modalInstance и жестко закодированы для открытия модального, вы можете использовать это событие. Тайм-аут $не является хорошим решением.

Вы можете сделать (Bootstrap3):

$("#" + modalId).on("shown.bs.modal", function() {
    angular.element("[name='name']").focus();
});

В modalInstance вы можете посмотреть на библиотеку, как выполнить код после открытого модала.

Не используйте $timeout, как это, $timeout может быть 0, 1, 10, 30, 50, 200 или более, это будет зависеть от клиентского компьютера и процесс для открытия модального.

Не используйте $timeout, если метод подскажет вам, когда вы можете сфокусироваться;)

Я надеюсь, что эта помощь!:)

2
ответ дан Filipe Cotrim Melo 21 сент. '15 в 17:35
источник поделиться

Все предыдущие ответы не работают, если желаемый элемент фокусировки вводится в шаблон директивы. Следующая директива соответствует как элементам с простым элементом, так и директивой (я написал это в typescript). он принимает селектор для внутреннего фокусируемого элемента. если вам просто нужно сфокусировать элемент self - не отправляйте в директиву какой-либо параметр выбора:

module APP.Directives {

export class FocusOnLoadDirective implements ng.IDirective {
    priority = 0;
    restrict = 'A';

    constructor(private $interval:any, private $timeout:any) {

    }

    link = (scope:ng.IScope, element:JQuery, attrs:any) => {
        var _self = this;
        var intervalId:number = 0;


        var clearInterval = function () {
            if (intervalId != 0) {
                _self.$interval.cancel(intervalId);
                intervalId = 0;
            }
        };

        _self.$timeout(function(){

                intervalId = _self.$interval(function () {
                    let focusableElement = null;
                    if (attrs.focusOnLoad != '') {
                        focusableElement = element.find(attrs.focusOnLoad);
                    }
                    else {
                        focusableElement = element;
                    }
                    console.debug('focusOnLoad directive: trying to focus');
                    focusableElement.focus();
                    if (document.activeElement === focusableElement[0]) {
                        clearInterval();
                    }
                }, 100);

                scope.$on('$destroy', function () {
                    // Make sure that the interval is destroyed too
                    clearInterval();
                });

        });
    };

    public static factory = ():ng.IDirectiveFactory => {
        let directive = ($interval:any, $timeout:any) => new FocusOnLoadDirective($interval, $timeout);
        directive.$inject = ['$interval', '$timeout'];
        return directive;
    };
}

angular.module('common').directive('focusOnLoad', FocusOnLoadDirective.factory());

}

пример использования для простого элемента:

<button tabindex="0" focus-on-load />

пример использования для внутреннего элемента (обычно для динамического вложенного элемента, такого как директива с шаблоном):

<my-directive focus-on-load="input" />

вы можете использовать любой селектор jQuery вместо "ввода"

2
ответ дан Ofir Meguri 09 марта '16 в 12:26
источник поделиться

Я редактирую директиву Mark Rajcok focusMe для работы с несколькими фокусами в одном элементе.

HTML:

<input  focus-me="myInputFocus"  type="text">

в контроллере AngularJs:

$scope.myInputFocus= true;

Директива AngulaJS:

app.directive('focusMe', function ($timeout, $parse) {
    return {
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                if (value === true) {
                    $timeout(function () {
                        scope.$apply(model.assign(scope, false));
                        element[0].focus();
                    }, 30);
                }
            });
        }
    };
});
2
ответ дан Mohamad Khani 21 июля '14 в 14:53
источник поделиться

Следующая директива сделала трюк для меня. Используйте тот же атрибут html автофокуса для ввода.

.directive('autofocus', [function () {
    return {
        require : 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.focus();
        }
    };
}])
2
ответ дан Kishore Relangi 06 авг. '15 в 6:41
источник поделиться

Это легко.. попробуйте это

HTML

<select id="ddl00">  
 <option>"test 01"</option>  
</select>

Javascript

document.getElementById("ddl00").focus();
1
ответ дан isanka thalagala 28 июля '17 в 11:20
источник поделиться

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

Критерии: 1. Решение должно быть независимым от возможностей родительского контроллера, чтобы увеличить повторное использование. 2. Избегайте использования $watch для отслеживания некоторых условий, это медленное, увеличивает размер цикла дайджеста и упрощает тестирование. 3. Избегайте $timeout или $scope. $Apply() запускает цикл дайджеста. 4. Элемент ввода присутствует в элементе, где используется Директива.

Это решение, которое мне больше всего понравилось:

Директива:

.directive('focusInput', [ function () {
    return {
        scope: {},
        restrict: 'A',
        compile: function(elem, attr) {
            elem.bind('click', function() {
                elem.find('input').focus();                
            });
        }        
    };
}]);

Html:

 <div focus-input>
     <input/>
 </div>

Я надеюсь, что это поможет кому-то!

1
ответ дан xiaoma 18 февр. '15 в 16:10
источник поделиться

Просто бросьте кофе.

app.directive 'ngAltFocus', ->
    restrict: 'A'
    scope: ngAltFocus: '='
    link: (scope, el, attrs) ->
        scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv
0
ответ дан Talasan Nicholson 11 июня '14 в 1:16
источник поделиться

Не уверен, что если полагаться на тайм-аут, это хорошая идея, но это работает для ng-repeat, потому что этот код запускается ПОСЛЕ angularjs обновляет DOM, поэтому вы убедитесь, что все объекты:

myApp.directive('onLastRepeat', [function () {
        return function (scope, element, attrs) {
            if (scope.$last) setTimeout(function () {
                scope.$emit('onRepeatLast', element, attrs);
            }, 1);
        };
    }]);
    //controller for grid
    myApp.controller('SimpleController', ['$scope', '$timeout', '$http', function ($scope, $timeout, $http)
    {
        var newItemRemoved = false;
        var requiredAlert = false;
        //this event fires up when angular updates the dom for the last item
        //it observed, so here, we stop the progress bar
        $scope.$on('onRepeatLast', function (scope, element, attrs) {
            //$scope.complete();
            console.log('done done!');
            $("#txtFirstName").focus();
        });
    }]);
0
ответ дан Alex 06 февр. '15 в 23:40
источник поделиться

вы можете использовать директиву ниже, которая получает значение bool в html-вводе для фокусировки на нем...

//js file
angular.module("appName").directive("ngFocus", function () {
       return function (scope, elem, attrs, ctrl) {
             if (attrs.ngFocus === "true") {
                 $(elem).focus();
             }
             if (!ctrl) {
                 return;
             }
       elem.on("focus", function () {
            elem.addClass("has-focus");
            scope.$apply(function () {
                ctrl.hasFocus = true;
            });
        });
    };
});

<!-- html file -->
<input type="text" ng-focus="boolValue" />

Вы даже можете установить функцию в своем контроллере на значение директивы ngFocus обратите внимание на код ниже...

<!-- html file -->
<input type="text" ng-focus="myFunc()" />


//controller file
$scope.myFunc=function(){
      if(condition){
          return true;
      }else{
          return false;
      }
}

эта директива должна произойти при визуализации html-страницы.

0
ответ дан pejman 29 дек. '17 в 16:10
источник поделиться
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос