Автофокус в ng-repeat в angularjs

Я использую ng-repeat для получения нескольких телефонных номеров.

<div ng-repeat="phone in phones">
    <input ng-model="phone" type="text" autofocus="autofocus"> 
</div>
<a ng-click="addPhone()">Add Phone</a>

В контроллерах

$scope.addPhone = function() {
    $scope.phones.add('');
}

Всякий раз, когда я добавляю новый телефон, он автоматически автофокусирует ввод. Это прекрасно работает. Но когда я перезагружаю (открываю по ссылке) представление, оно прокручивается до последней записи. Как избежать автофокуса при первой загрузке вида. Только я хочу автофокус, когда я добавляю новый телефон.


person Fizer Khan    schedule 25.01.2014    source источник


Ответы (4)


Пытаться:

<div ng-repeat="phone in phones">
    <input ng-model="phone" type="text" ng-if="$index == focusIndex" autofocus>
    <input ng-model="phone" type="text" ng-if="$index != focusIndex">
  </div>
  <a ng-click="addPhone()">Add Phone</a>

JS:

$scope.addPhone = function() {
    $scope.phones.push('Phone' + Math.random());

    $scope.focusIndex = $scope.phones.length-1;
  }

ДЕМО

Решение с использованием пользовательского атрибута:

<div ng-repeat="phone in phones">
    <input ng-model="phone" type="text" custom-autofocus="$index == focusIndex" >
  </div>
  <a ng-click="addPhone()">Add Phone</a>

JS:

.directive('customAutofocus', function() {
  return{
         restrict: 'A',

         link: function(scope, element, attrs){
           scope.$watch(function(){
             return scope.$eval(attrs.customAutofocus);
             },function (newValue){
               if (newValue === true){
                   element[0].focus();//use focus function instead of autofocus attribute to avoid cross browser problem. And autofocus should only be used to mark an element to be focused when page loads.
               }
           });
         }
     };
})

ДЕМО

person Khanh TO    schedule 25.01.2014
comment
Хорошее решение. Лучшей практикой является не ставить перед пользовательскими директивами префикс ng в случае конфликтов с будущими версиями angular. - person Gruff Bunny; 25.01.2014
comment
Я только что протестировал это решение (ссылка DEMO plunker) с Chrome v52: я не получаю фокус на последнем INPUT... Может ли это решение устареть? - person Didier68; 12.09.2016
comment
@ Didier68: вы получаете фокус только при добавлении нового телефона. Если вы хотите сосредоточиться на загрузке страницы, вам нужно установить индекс по умолчанию на focusIndex: plnkr. co/edit/lN5W94oDeiqR6HMUFMqz?p=preview - person Khanh TO; 16.09.2016
comment
Вместо использования условия custom-autofocus=$index == focusIndex просто используйте custom-autofocus=$last - person user626710; 08.12.2017
comment
@ user626710: в этом случае ваш подход хорош, но использование focusIndex является более общим подходом - person Khanh TO; 09.12.2017

Вы можете использовать эту директиву: https://github.com/aikus/ng-focus-if/blob/master/ng-focus-if.js Например:

<div ng-repeat="phone in phones">
   <input ng-model="phone" type="text" ng-focus-if="1==1"> 
</div>
<a ng-click="addPhone()">Add Phone</a>
person Nikita    schedule 16.09.2014

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

Решением будет применение атрибута autofocus при необходимости.

<div ng-repeat="phone in phones">
    <input ng-model="phone" type="text" autofocus="{{phone.autofocus || 'false'}}"> 
</div>
<a ng-click="addPhone()">Add Phone</a>

Контроллер:

$scope.addPhone = function() {
    $scope.phones[$scope.phones.length-1].autofocus = 'false'; // unfocus the old
    $scope.phones.add('');
    $scope.phones[$scope.phones.length-1].autofocus = 'true'; // focus the new
}
person ncabral    schedule 25.01.2014
comment
Это всегда фокусирует элемент, даже если выражение оценивается как «ложь». Использование Хрома. - person Sam Barnum; 09.04.2014
comment
Логические атрибуты в HTML являются ложными только тогда, когда они не существуют. stackoverflow.com/a/25449778/41908 - person Rob; 24.01.2017

Многократное использование автофокуса на вашей странице не запрещено, но, судя по документации, выглядит неправильно, https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input

Там написаноOnly one form element in a document can have the autofocus attribute

autofocus HTML5 Этот логический атрибут позволяет указать, что элемент управления формы должен иметь фокус ввода при загрузке страницы, если только пользователь не переопределит его, например, введя другой элемент управления. Только один элемент формы в документе может иметь атрибут autofocus, который является логическим значением. Его нельзя применить, если для атрибута type установлено значение hidden (то есть вы не можете автоматически установить фокус на скрытый элемент управления).

Я бы не стал использовать autofocus внутри ng-repeat и устанавливать фокус вручную после его добавления.

person allenhwkim    schedule 25.01.2014