Установите фокус элемента в угловом пути
после поиска примеров того, как установить элементы фокуса с угловым, я увидел, что большинство из них используют некоторую переменную, чтобы следить за затем установить фокус, и большинство из них используют одну другую переменную для каждого поля, которое они хотят установить фокус. В форме, с большим количеством полей, что подразумевает в большом количестве различных переменных.
имея в виду способ jquery, но желая сделать это угловым способом, я сделал решение, которое мы устанавливаем фокус в любой функции, используя идентификатор элемента, так как я очень новичок в угловой, я хотел бы получить некоторые мнения, если это правильно, есть проблемы, что угодно, все, что может помочь мне сделать это лучше в угловой.
в принципе, я создаю директиву, которая отслеживает значение области, определенное пользователем с директивой, или focusElement по умолчанию, и когда это значение совпадает с идентификатором элемента, этот элемент сам устанавливает фокус.
angular.module('appnamehere')
.directive('myFocus', function () {
return {
restrict: 'A',
link: function postLink(scope, element, attrs) {
if (attrs.myFocus == "") {
attrs.myFocus = "focusElement";
}
scope.$watch(attrs.myFocus, function(value) {
if(value == attrs.id) {
element[0].focus();
}
});
element.on("blur", function() {
scope[attrs.myFocus] = "";
scope.$apply();
})
}
};
});
вход, который должен получить фокус по какой-то причине, будет делать это так
<input my-focus id="input1" type="text" />
здесь любой элемент для установки фокуса:
<a href="" ng-click="clickButton()" >Set focus</a>
и пример функции, которая устанавливает фокус:
$scope.clickButton = function() {
$scope.focusElement = "input1";
}
- Это хорошее решение в угловой? Есть ли у него проблемы, которые с моим плохим опытом я еще не вижу?
6 ответов:
проблема с вашим решением заключается в том, что оно не работает хорошо, когда привязано к другим директивам, которые создают новую область, например
ng-repeat. Лучшим решением было бы просто создать сервисную функцию, которая позволяет вам принудительно фокусировать элементы внутри ваших контроллеров или декларативно фокусировать элементы в контроллере. формат html.JAVASCRIPT
сервис
.factory('focus', function($timeout, $window) { return function(id) { // timeout makes sure that it is invoked after any other event has been triggered. // e.g. click events that need to run before the focus or // inputs elements that are in a disabled state but are enabled when those events // are triggered. $timeout(function() { var element = $window.document.getElementById(id); if(element) element.focus(); }); }; });директива
.directive('eventFocus', function(focus) { return function(scope, elem, attr) { elem.on(attr.eventFocus, function() { focus(attr.eventFocusId); }); // Removes bound events in the element itself // when the scope is destroyed scope.$on('$destroy', function() { elem.off(attr.eventFocus); }); }; });контроллер
.controller('Ctrl', function($scope, focus) { $scope.doSomething = function() { // do something awesome focus('email'); }; });HTML
<input type="email" id="email" class="form-control"> <button event-focus="click" event-focus-id="email">Declarative Focus</button> <button ng-click="doSomething()">Imperative Focus</button>
об этом решении мы могли бы просто создать директиву и прикрепить ее к элементу DOM, который должен получить фокус, когда выполняется данное условие. Следуя этому подходу, мы избегаем связывания контроллера с идентификаторами элементов DOM.
пример директивы кода:
gbndirectives.directive('focusOnCondition', ['$timeout', function ($timeout) { var checkDirectivePrerequisites = function (attrs) { if (!attrs.focusOnCondition && attrs.focusOnCondition != "") { throw "FocusOnCondition missing attribute to evaluate"; } } return { restrict: "A", link: function (scope, element, attrs, ctrls) { checkDirectivePrerequisites(attrs); scope.$watch(attrs.focusOnCondition, function (currentValue, lastValue) { if(currentValue == true) { $timeout(function () { element.focus(); }); } }); } }; } ]);возможное использование
.controller('Ctrl', function($scope) { $scope.myCondition = false; // you can just add this to a radiobutton click value // or just watch for a value to change... $scope.doSomething = function(newMyConditionValue) { // do something awesome $scope.myCondition = newMyConditionValue; };});
HTML
<input focus-on-condition="myCondition">
мне нравится избегать поиска DOM, часов и глобальных излучателей, когда это возможно, поэтому я использую более прямой подход. Используйте директиву для назначения простой функции, которая фокусируется на элементе директивы. Затем вызовите эту функцию везде, где это необходимо в пределах области контроллера.
вот упрощенный подход для присоединения его к области. См. полный фрагмент кода для обработки синтаксиса controller-as.
Вы можете попробовать
angular.element('#<elementId>').focus();например.
angular.element('#txtUserId').focus();его работа для меня.
другим вариантом было бы использовать угловые встроенные в паб-саб архитектуры для того, чтобы уведомить вашу директиву, чтобы сосредоточиться. Подобно другим подходам, но тогда он не привязан непосредственно к свойству, а вместо этого прослушивает его область для определенного ключа.
:angular.module("app").directive("focusOn", function($timeout) { return { restrict: "A", link: function(scope, element, attrs) { scope.$on(attrs.focusOn, function(e) { $timeout((function() { element[0].focus(); }), 10); }); } }; });HTML:
:<input type="text" name="text_input" ng-model="ctrl.model" focus-on="focusTextInput" />//Assume this is within your controller //And you've hit the point where you want to focus the input: $scope.$broadcast("focusTextInput");
я предпочитал использовать выражение. Это позволяет мне делать такие вещи, как сосредоточиться на кнопке, когда поле действительно, достигает определенной длины и, конечно, после загрузки.
<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">в сложной форме это также уменьшает необходимость создания дополнительных переменных области для целей фокусировки.
Comments