- Wenn ein Modal geöffnet wird, konzentrieren Sie sich auf einen vordefinierten <Eingang> in diesem Modal.
Definieren Sie eine Direktive und lassen Sie sie $ eine Eigenschaft / einen Trigger beobachten, damit sie weiß, wann das Element fokussiert werden muss:
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));
});
}
};
}]);
Plunker
Das $ timeout scheint erforderlich zu sein, um dem Modal Zeit zum Rendern zu geben.
'2.' Stellen Sie den Fokus jedes Mal ein, wenn <Eingabe> sichtbar wird (z. B. durch Klicken auf eine Schaltfläche).
Erstellen Sie eine Direktive im Wesentlichen wie oben. Beobachten Sie eine Scope-Eigenschaft und führen Sie sie aus, wenn sie wahr wird (legen Sie sie in Ihrem ng-click-Handler fest) element[0].focus()
. Abhängig von Ihrem Anwendungsfall benötigen Sie möglicherweise ein $ Timeout für diesen:
<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;
//});
}
});
}
};
});
Plunker
Update 7/2013 : Ich habe gesehen, dass einige Leute meine ursprünglichen Anweisungen zum Isolieren des Gültigkeitsbereichs verwenden und dann Probleme mit eingebetteten Eingabefeldern haben (dh einem Eingabefeld im Modal). Eine Richtlinie ohne neuen Geltungsbereich (oder möglicherweise mit einem neuen Geltungsbereich für Kinder) sollte einen Teil der Schmerzen lindern. Daher habe ich oben die Antwort aktualisiert, um keine isolierten Bereiche zu verwenden. Unten ist die ursprüngliche Antwort:
Ursprüngliche Antwort für 1. unter Verwendung eines isolierten Bereichs:
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();
});
}
});
}
};
});
Plunker .
Ursprüngliche Antwort für 2. unter Verwendung eines isolierten Bereichs:
<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;
//});
}
});
}
};
});
Plunker .
Da wir die Eigenschaft trigger / focusInput in der Direktive zurücksetzen müssen, wird '=' für die bidirektionale Datenbindung verwendet. In der ersten Anweisung war '@' ausreichend. Beachten Sie auch, dass wir bei Verwendung von '@' den Triggerwert mit "true" vergleichen, da @ immer zu einer Zeichenfolge führt.