Je veux que mon application renseigne une valeur dans le $scope AngularJs quand je reçois un événement système…mais ça ne marche pas !
Pourtant ça parait simple mais les événements systèmes sont traités en dehors d’AngularJs donc on ne peut pas faire un simple :
$scope.maVariable = 'toto';
Alors c’est quoi l’astuce?
Le problème :
Pour expliquer mon problème d’origine, j’ai voulu faire le bout de code suivant :
angular.module('monApp').run(['$scope', function($scope) { document.addEventListener('deviceready', function() { $scope.maVariable = 'toto'; }); });
Un code tout simple qui enregistre la valeur ‘toto’ dans le $scope quand l’événement ‘deviceready’ est reçu par l’application.
On pourrait imaginer que événement serait l’événement reçu sur le bouton “back” physique du téléphone aussi :
document.addEventListener('backbutton', function(){});
A l’exécution tout se passe bien mais si on essaie d’afficher “$scope.maVariable” dans la vue, rien ne s’affiche.
L’explication :
Les événements systèmes sont gérés en dehors d’AngularJS, ce qui fait que l’on n’attribue pas notre valeur ‘toto’ au $scope Angular mais à une simple variable locale.
Pour appliquer notre valeur au $scope Angular il faut utiliser la méthode “$apply”. Mais qu’est ce que c’est cette méthode?
$scope.$apply() prend une fonction ou une expression Angular comme paramètre et l’exécute puis appelle $scope.$digest() qui va mettre à jour le binding ou les “watchers”.
Pour corriger notre code écrit plus haut il nous suffit donc d’écrire :
angular.module('monApp').run(['$scope', function($scope) { document.addEventListener('deviceready', function() { $scope.$apply(function() { $scope.maVariable = 'toto'; }); }); });
Et ainsi notre variable est bien mise à jour depuis l’événement système !