각도로 요소 초점 설정
각도로 초점 요소를 설정하는 방법에 대한 예제를 찾은 후, 대부분은 변수를 사용하여 초점을보고 초점을 설정하고 대부분은 초점을 설정하려는 각 필드마다 하나의 다른 변수를 사용한다는 것을 알았습니다. 많은 필드를 가진 형태로, 그것은 많은 다른 변수를 의미합니다.
jquery 방식을 염두에두고 각도 방식으로하고 싶을 때 요소의 ID를 사용하여 모든 기능에 초점을 맞추는 솔루션을 만들었으므로 각도가 매우 새롭기 때문에 의견이 있으면 그 방법은 옳고 문제가 있습니다.
기본적으로 지시어 또는 기본 focusElement를 사용하여 사용자가 정의한 범위 값을보고 지시문을 작성하고 해당 값이 요소의 ID와 동일하면 해당 요소 세트가 자체적으로 초점을 설정합니다.
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";
}
각도에서 좋은 해결책입니까? 내 경험이 좋지 않아 아직 보지 못하는 문제가 있습니까?
솔루션의 문제는 새로운 범위를 만드는 다른 지시문에 묶여 있으면 잘 작동하지 않는다는 것 ng-repeat
입니다. 더 나은 솔루션은 단순히 컨트롤러 내에서 요소를 집중적으로 집중 시키거나 HTML에서 요소를 선언적으로 집중시킬 수있는 서비스 기능을 만드는 것입니다.
자바 스크립트
서비스
.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>
About this solution, we could just create a directive and attach it to the DOM element that has to get the focus when a given condition is satisfied. By following this approach we avoid coupling controller to DOM element ID's.
Sample code directive:
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();
});
}
});
}
};
}
]);
A possible usage
.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">
I like to avoid DOM lookups, watches, and global emitters whenever possible, so I use a more direct approach. Use a directive to assign a simple function that focuses on the directive element. Then call that function wherever needed within the scope of the controller.
Here's a simplified approach for attaching it to scope. See the full snippet for handling controller-as syntax.
Directive:
app.directive('inputFocusFunction', function () {
'use strict';
return {
restrict: 'A',
link: function (scope, element, attr) {
scope[attr.inputFocusFunction] = function () {
element[0].focus();
};
}
};
});
and in html:
<input input-focus-function="focusOnSaveInput" ng-model="saveName">
<button ng-click="focusOnSaveInput()">Focus</button>
or in the controller:
$scope.focusOnSaveInput();
angular.module('app', [])
.directive('inputFocusFunction', function() {
'use strict';
return {
restrict: 'A',
link: function(scope, element, attr) {
// Parse the attribute to accomodate assignment to an object
var parseObj = attr.inputFocusFunction.split('.');
var attachTo = scope;
for (var i = 0; i < parseObj.length - 1; i++) {
attachTo = attachTo[parseObj[i]];
}
// assign it to a function that focuses on the decorated element
attachTo[parseObj[parseObj.length - 1]] = function() {
element[0].focus();
};
}
};
})
.controller('main', function() {});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<body ng-app="app" ng-controller="main as vm">
<input input-focus-function="vm.focusOnSaveInput" ng-model="saveName">
<button ng-click="vm.focusOnSaveInput()">Focus</button>
</body>
Edited to provide more explanation about the reason for this approach and to extend the code snippet for controller-as use.
You can try
angular.element('#<elementId>').focus();
for eg.
angular.element('#txtUserId').focus();
its working for me.
Another option would be to use Angular's built-in pub-sub architecture in order to notify your directive to focus. Similar to the other approaches, but it's then not directly tied to a property, and is instead listening in on it's scope for a particular key.
Directive:
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" />
Controller:
//Assume this is within your controller
//And you've hit the point where you want to focus the input:
$scope.$broadcast("focusTextInput");
I prefered to use an expression. This lets me do stuff like focus on a button when a field is valid, reaches a certain length, and of course after load.
<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">
On a complex form this also reduces need to create additional scope variables for the purposes of focusing.
See https://stackoverflow.com/a/29963695/937997
참고URL : https://stackoverflow.com/questions/25596399/set-element-focus-in-angular-way
'IT story' 카테고리의 다른 글
Amazon 용 AWS_ACCESS_KEY_ID를 어떻게 얻습니까? (0) | 2020.08.03 |
---|---|
git repo의 하위 디렉토리 만 Heroku에 배포 / 푸시하는 방법은 무엇입니까? (0) | 2020.08.03 |
jquery는 자바 스크립트 라이브러리 또는 프레임 워크입니까? (0) | 2020.08.03 |
Groovy에서 문자열이 null이 아닌 공백인지 어떻게 알 수 있습니까? (0) | 2020.08.03 |
SCSS / SASS로 퍼센트 계산 (0) | 2020.08.03 |