Настройка фокуса на поле ввода после ng-show
Возможно ли установить фокус поля ввода через контроллер после загрузки данных (через $resource в этом случае)?
Ввод скрывается с помощью ng-show, пока данные не будут возвращены из API, но я не могу найти способ установить фокус на вход. Я знаю имя ng-модели ввода и имя ввода, что означает, что я мог бы сделать это через jQuery, но я предпочел бы сделать это, если возможно, способом AngularJS.
Я пробовал здесь множество примеров директив, но все они кажутся pre-1.2 ng-focus, полагайтесь на ng-click сначала с одной кнопки (не может быть в моем случае) т.
Любые советы очень благодарны.
Ответы
Ответ 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();
}
}