(EDIT : J'ai ajouté une solution mise à jour sous cette explication)
Mark Rajcok est l'homme de la situation... et sa réponse est valable, mais elle... a avait un défaut (désolé Mark)...
...Essayez d'utiliser le booléen pour vous concentrer sur l'entrée, puis brouillez l'entrée, puis essayez de l'utiliser à nouveau pour vous concentrer sur l'entrée. Cela ne fonctionnera pas, à moins que vous ne réinitialisiez le booléen à false, puis $digest, puis le réinitialisiez à true. Même si vous utilisez une comparaison de chaînes dans votre expression, vous serez obligé de changer la chaîne en quelque chose d'autre, $digest, puis de la changer à nouveau. (Ce problème a été résolu avec le gestionnaire d'événements de flou).
Je propose donc cette solution alternative :
Utilisez un événement, la fonctionnalité oubliée d'Angular.
JavaScript adore les événements après tout. Les événements sont par nature faiblement couplés, et mieux encore, vous évitez d'ajouter un autre $watch à votre $digest.
app.directive('focusOn', function() {
return function(scope, elem, attr) {
scope.$on(attr.focusOn, function(e) {
elem[0].focus();
});
};
});
Donc maintenant vous pouvez l'utiliser comme ceci :
<input type="text" focus-on="newItemAdded" />
et ensuite n'importe où dans votre application...
$scope.addNewItem = function () {
/* stuff here to add a new item... */
$scope.$broadcast('newItemAdded');
};
C'est génial parce que vous pouvez faire toutes sortes de choses avec quelque chose comme ça. D'une part, vous pouvez vous connecter à des événements qui existent déjà. D'autre part, vous pouvez faire quelque chose d'intelligent en faisant en sorte que différentes parties de votre application publient des événements auxquels d'autres parties de votre application peuvent s'abonner.
Quoi qu'il en soit, ce type de chose me semble être "événementiel". Je pense qu'en tant que développeurs Angular, nous essayons vraiment d'enfoncer des chevilles en forme de $scope dans des trous en forme d'événement.
Est-ce la meilleure solution ? Je ne sais pas. Elle est a solution.
Solution actualisée
Après le commentaire de @ShimonRachlenko ci-dessous, j'ai légèrement modifié ma méthode de travail. Maintenant, j'utilise une combinaison d'un service et d'une directive qui gère un événement "en coulisse" :
Pour le reste, c'est le même principe que celui décrit ci-dessus.
Voici une démonstration rapide de Plunk
Utilisation
<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
focus('focusMe');
});
Source
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);
});
}
});