2016-08-17 2 views
1

У меня есть приложение iOS, использующее angularJS и ионный. Я пытаюсь переключить клавиатуру на следующее поле ввода, когда нажата кнопка «Возврат». Вот HTML-код, где нг-повтор существует:Как установить фокус на следующее поле ввода, генерируемое ng-repeat?

  <div class="row item-list" ng-repeat="item in shoppingList"> 
       <div class="col col-10 col-check" ng-click="checkItem($index)"> 
        <i class="icon ion-checkmark-round" ng-if="item.Action == 'check'"></i> 
       </div> 
       <div class="col col-memo" ng-click="updateMemo($index)"> 
        <label class="item-list item-input"> 
         <input id="inputText" type="text" placeholder="" ng-model="item.EventContent" on-return="nextLine($index)"/> 
        </label> 
       </div> 
      </div> 

Вы можете увидеть в моем входном элементе у меня есть «на возврате =» nextLine ($ индекс) «». Там я использую свою пользовательскую директиву, которая используется, когда кнопка возврата хита:

.directive('onReturn', function() { 
return function (scope, element, attrs) { 
    element.bind("keydown keypress", function (event) { 
     if (event.which === 13) { 
      scope.$apply(function() { 
       scope.$eval(attrs.onReturn); 
      }); 
      event.preventDefault(); 
     } 
    }); 
}; 
}); 

Который называет мою nextLine функции в моем контроллере:

myScope.nextLine = function (index) { 
    //get next html input element and .setFocus() 
} 

где индекс индекс поля ввода тока. Мне нужен способ получить следующий элемент ввода HTML и установить там фокус. Любая помощь приветствуется.

+0

Не используйте 'рамки $ apply' непосредственно, вместо того, чтобы обернуть в' $ таймаута() '- это делает«умный»использование' $ применяется '- не« жестокий ». – DotBot

ответ

1

По моему опыту, более управляемый событиями метод лучше подходит для управления фокусом. Передайте событие вашему методу nextLine. Предполагая, что вы только с помощью Jquery свет, вы бы в конечном итоге с чем-то вроде этого:

//add closest method to jQuery light 
$.fn.closest = function (selector) { 
    var el = this[0]; 
    while (el && self.matches(el, selector)) { 
    el = el.parentElement; 
    } 
    return $(el); 
}; 

myScope.nextLine = function (event) { 
    var nextInput = $(event.target).closest("[ng-repeat]").find("input"); 
    if(nextInput[0]){ 
    nextInput[0].focus(); 
    } 
} 
1

Прежде всего, это не рекомендуется использовать несколько экземпляров директив со слушателями событий DOM. Что делать, если у вас было 1000 директив, прослушивающих одно и то же событие «keydown»? это были бы орехи.

Возможно, вам стоит подойти к этому с помощью хорошего «jQuery: добавить прослушиватель событий« keydown »к элементу контейнера, а затем просто перебрать поля ввода с каждым нажатием« return ». : Working demo here

Упрощенная версия шаблона:

<div class="items-lists" on-return> 
    <input type="text" ng-repeat="item in shoppingList" class="item-list"> 
</div> 

И тогда в вашей директиве:

angular.module('MyApp') 
    .directive('onReturn', function() { 
     return { 
      restrict: 'A', 
      link: function(scope, element, attr) { 
       $(element).on("keydown keypress", function(event) { 
        if (event.which === 13) { 
         scope.nextLine(); 
         event.preventDefault(); 
        } 
       }); 

       //get next html input element and set focus() 
       scope.nextLine = function() { 
        var nextInput = $(element).find('input:focus').next('input'); 
        var firstInput = $(element).find('input')[0]; 
        nextInput.length ? nextInput.focus() : firstInput.focus(); 
       } 
      } 
     } 
    }); 

Решение # 2:

Другим подходом будет использование ng-focus, которое принимает булево выражение. Вы можете создать функцию ng-click для каждого элемента внутри вашего ng-repeat, который устанавливает его как «selected» и отменяет выбор остального. . Затем оценить item.selected в ваших полях ввода для достижения фокуса:

<div class="items-lists"> 
    <input ng-repeat="item in shoppingList" ng-focus="item.selected" ng-click="selectItem(item)" class="item-list"> 
</div> 
Смежные вопросы