AngularJS의 입력 필드에 초점을 맞추는 ‘각도’는 무엇입니까?
보다 구체적인 요구 사항 :
- 때 모달은 미리 정의에 설정 초점 열립니다
<input>
이 모달 내부. <input>
(예를 들어 일부 버튼을 클릭하여) 보일 때 마다 초점을 설정하십시오.
나는 첫 번째 요구 사항 달성하기 위해 노력 과를autofocus
, 그러나 이것은 모달 처음 열리고 특정 브라우저 (파이어 폭스에서 작동하지 않는 등) 경우에만 작동합니다.
도움을 주시면 감사하겠습니다.
답변
- 모달이 열리면이 모달 내부의 사전 정의 된 <입력>에 초점을 설정하십시오.
지시어를 정의하고 속성 / 트리거를 $ watch하여 요소를 언제 포커스해야하는지 알 수있게하십시오.
Name: <input type="text" focus-me="shouldBeOpen">
app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
return {
//scope: true, // optionally create a child scope
link: function (scope, element, attrs) {
var model = $parse(attrs.focusMe);
scope.$watch(model, function (value) {
console.log('value=', value);
if (value === true) {
$timeout(function () {
element[0].focus();
});
}
});
// to address @blesh's comment, set attribute value to 'false'
// on blur event:
element.bind('blur', function () {
console.log('blur');
scope.$apply(model.assign(scope, false));
});
}
};
}]);
모달 시간을 렌더링하는 데 $ timeout이 필요한 것 같습니다.
‘2.’ <입력>이 보일 때마다 (예 : 버튼을 클릭하여) 초점을 설정하십시오.
본질적으로 위와 같은 지시문을 작성하십시오. 범위 속성을 확인하고 true가되면 (ng-click 핸들러에서 설정) 실행하십시오 element[0].focus()
. 사용 사례에 따라 $ timeout이 필요하거나 필요하지 않을 수 있습니다.
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.focusMe, function(value) {
if(value === true) {
console.log('value=',value);
//$timeout(function() {
element[0].focus();
scope[attrs.focusMe] = false;
//});
}
});
}
};
});
2013 년 7 월 업데이트 : 소수의 사람들이 원래의 분리 범위 지시문을 사용하고 포함 된 입력 필드 (예 : 모달의 입력 필드)에 문제가 있음을 보았습니다. 새로운 범위가 없거나 (또는 새로운 자식 범위가없는) 지시문은 약간의 고통을 완화해야합니다. 따라서 위의 격리 범위를 사용하지 않도록 답변을 업데이트했습니다. 아래는 원래 답변입니다.
분리 범위를 사용하는 1에 대한 원래 답변 :
Name: <input type="text" focus-me="{{shouldBeOpen}}">
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '@focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === "true") {
$timeout(function() {
element[0].focus();
});
}
});
}
};
});
플 런커 .
분리 범위를 사용하여 2에 대한 원래 답변 :
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" focus-me="focusInput">
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '=focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === true) {
//console.log('trigger',value);
//$timeout(function() {
element[0].focus();
scope.trigger = false;
//});
}
});
}
};
});
플 런커 .
지시문에서 trigger / focusInput 속성을 재설정해야하므로 양방향 데이터 바인딩에는 ‘=’가 사용됩니다. 첫 번째 지시문에서 ‘@’이면 충분했습니다. 또한 @을 사용하면 @가 항상 문자열이되므로 트리거 값을 “true”와 비교합니다.
답변
(편집 :이 설명 아래에 업데이트 된 솔루션을 추가했습니다)
마크 Rajcok 그 사람 … 그리고 그의 대답은 올바른 대답이지만, 한 결함 (죄송 마크)했다 …
… 부울을 사용하여 입력에 초점을 맞춘 다음 입력을 흐리게 한 다음 다시 입력에 초점을 맞추십시오. 부울을 false로 재설정 한 다음 $ digest를 재설정 한 다음 다시 true로 재설정하지 않으면 작동하지 않습니다. 식에 문자열 비교를 사용하더라도 문자열을 $ digest로 변경 한 다음 다시 변경해야합니다. (이는 blur 이벤트 핸들러로 해결되었습니다.)
따라서이 대체 솔루션을 제안합니다.
잊혀진 Angular의 기능인 이벤트를 사용하십시오.
JavaScript는 결국 이벤트를 좋아합니다. 이벤트는 본질적으로 느슨하게 결합되어 있으며 더 좋은 것은 $ digest에 $ watch를 추가하는 것을 피합니다.
app.directive('focusOn', function() {
return function(scope, elem, attr) {
scope.$on(attr.focusOn, function(e) {
elem[0].focus();
});
};
});
이제 다음과 같이 사용할 수 있습니다.
<input type="text" focus-on="newItemAdded" />
그런 다음 앱의 어느 곳에서나
$scope.addNewItem = function () {
/* stuff here to add a new item... */
$scope.$broadcast('newItemAdded');
};
이런 식으로 모든 종류의 일을 할 수 있기 때문에 이것은 굉장합니다. 하나, 당신은 이미 존재하는 이벤트에 묶을 수 있습니다. 또 다른 일로는 앱의 다른 부분이 구독 할 수있는 앱 게시 이벤트의 다른 부분을 가져서 스마트 한 일을 시작합니다.
어쨌든, 이런 종류의 일이 나에게 “사건 주도”를 외칩니다. Angular 개발자로서 $ scope 모양의 페그를 이벤트 모양 구멍에 망치려고 열심히 노력한다고 생각합니다.
최고의 솔루션입니까? 난 몰라 그것은이다 솔루션입니다.
업데이트 된 솔루션
아래의 @ ShimonRachlenko의 의견 후에이 작업을 약간 변경했습니다. 이제 “장면에서”이벤트를 처리하는 지시문과 서비스를 조합하여 사용합니다.
그 외에는 위에서 설명한 것과 동일한 원칙입니다.
용법
<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
focus('focusMe');
});
출처
app.directive('focusOn', function() {
return function(scope, elem, attr) {
scope.$on('focusOn', function(e, name) {
if(name === attr.focusOn) {
elem[0].focus();
}
});
};
});
app.factory('focus', function ($rootScope, $timeout) {
return function(name) {
$timeout(function (){
$rootScope.$broadcast('focusOn', name);
});
}
});
답변
나는 당신이 정말로 필요한 모든 것이 이것 일 때 다른 대답 중 일부가 지나치게 복잡하다는 것을 발견했습니다
app.directive('autoFocus', function($timeout) {
return {
restrict: 'AC',
link: function(_scope, _element) {
$timeout(function(){
_element[0].focus();
}, 0);
}
};
});
사용법은
<input name="theInput" auto-focus>
우리는 타임 아웃을 사용하여 DOM의 것들이 0이더라도 렌더링 할 수있게합니다. 적어도 그것을 기다립니다.
답변
HTML에는 속성이 autofocus
있습니다.
<input type="text" name="fname" autofocus>
답변
각도에 내장 된 jqlite 기능을 사용할 수도 있습니다.
angular.element('.selector').trigger('focus');
답변
이것은 입력 제어에 초점을 맞추는 각도 방식으로 잘 작동합니다.
angular.element('#elementId').focus()
이것은 작업을 수행하는 순수한 각도 방법은 아니지만 구문은 각도 스타일을 따릅니다. Jquery는 Angular (jQLite => JQuery Light)를 사용하여 간접적으로 직접 DOM에 액세스합니다.
필요한 경우이 코드를 요소에 직접 액세스 할 수있는 간단한 각도 지시문에 쉽게 넣을 수 있습니다.
답변
나는 $ timeout이 요소를 창조에 집중시키는 좋은 방법이라고 생각하지 않습니다. 다음은 내장 된 각도 기능을 사용하여 각도 문서의 어두운 깊이에서 파낸 방법입니다. 사전 링크 및 사후 링크 기능을 위해 “link”속성을 “pre”및 “post”로 분리 할 수있는 방법에 주목하십시오.
작업 예 : http://plnkr.co/edit/Fj59GB
// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
return {
link: {
pre: function preLink(scope, element, attr) {
console.debug('prelink called');
// this fails since the element hasn't rendered
//element[0].focus();
},
post: function postLink(scope, element, attr) {
console.debug('postlink called');
// this succeeds since the element has been rendered
element[0].focus();
}
}
}
});
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />
전체 AngularJS 지시문 : https://docs.angularjs.org/api/ng/service/$compile