web-dev-qa-db-fra.com

Cordova + Angularjs + Device Ready

Je développe une application mobile utilisant Cordova et AngularJS. Comment puis-je limiter le démarrage d'AngluarJS avant que le périphérique Cordova ne soit prêt? En gros, je ne souhaite utiliser aucun des contrôleurs AngularJS avant que le périphérique ne soit prêt.

55
Anwer

Manuellement bootstrap votre Angular app:

Retirez votre ng-app attribut de votre code HTML, donc Angular ne commence pas lui-même.

Ajoutez quelque chose comme ceci à votre code JavaScript:

document.addEventListener("deviceready", function() {
    // retrieve the DOM element that had the ng-app attribute
    var domElement = document.getElementById(...) / document.querySelector(...);
    angular.bootstrap(domElement, ["angularAppName"]);
}, false);

Documentation angulaire pour les applications amorçage .

84
TheHippo

J'utilise la solution suivante, qui permet à AngularJS d'être initialisé avec Cordova ainsi que lorsqu'il est exécuté directement dans un navigateur . de mon développement a lieu. Vous devez supprimer la directive ng-app de votre page index.html principale, car c’est ce que l’amorçage manuel remplace.

UPDATE: Depuis, je suis passé à la méthode suivante, qui, je pense, est plus propre. Cela fonctionne pour Ionic ainsi que Vanilla Cordova/PhoneGap. Il devrait s'agir du dernier bit de JavaScript à exécuter - peut-être dans un script avant le /body tag.

  angular.element(document).ready(function () {
    if (window.cordova) {
      console.log("Running in Cordova, will bootstrap AngularJS once 'deviceready' event fires.");
      document.addEventListener('deviceready', function () {
        console.log("Deviceready event has fired, bootstrapping AngularJS.");
        angular.bootstrap(document.body, ['app']);
      }, false);
    } else {
      console.log("Running in browser, bootstrapping AngularJS now.");
      angular.bootstrap(document.body, ['app']);
    }
  });

Voici l'ancienne solution que j'ai utilisée:

// This is a function that bootstraps AngularJS, which is called from later code
function bootstrapAngular() {
    console.log("Bootstrapping AngularJS");
    // This assumes your app is named "app" and is on the body tag: <body ng-app="app">
    // Change the selector from "body" to whatever you need
    var domElement = document.querySelector('body');
    // Change the application name from "app" if needed
    angular.bootstrap(domElement, ['app']);
}

// This is my preferred Cordova detection method, as it doesn't require updating.
if (document.URL.indexOf( 'http://' ) === -1 
        && document.URL.indexOf( 'https://' ) === -1) {
    console.log("URL: Running in Cordova/PhoneGap");
    document.addEventListener("deviceready", bootstrapAngular, false);
} else {
    console.log("URL: Running in browser");
    bootstrapAngular();
}

Si vous rencontrez des problèmes avec la méthode de détection http/https, par exemple en chargeant une application Cordova sur le téléphone à partir du Web, vous pouvez utiliser la méthode suivante à la place:

function bootstrapAngular() {
    console.log("Bootstrapping AngularJS");
    // This assumes your app is named "app" and is on the body tag: <body ng-app="app">
    // Change the selector from "body" to whatever you need
    var domElement = document.querySelector('body');
    // Change the application name from "app" if needed
    angular.bootstrap(domElement, ['app']);
}

// This method of user agent detection also works, though it means you might have to maintain this UA list
if (navigator.userAgent.match(/(iOS|iPhone|iPod|iPad|Android|BlackBerry)/)) {
    console.log("UA: Running in Cordova/PhoneGap");
    document.addEventListener("deviceready", bootstrapAngular, false);
} else {
    console.log("UA: Running in browser");
    bootstrapAngular();
}

Notez que vous avez toujours besoin de la même fonction bootstrapAngular du premier exemple.

Pourquoi manuellement bootstrap AngularJS avec Cordova/PhoneGap/Ionic?

Certaines personnes arrivant ici pourraient ne pas savoir pourquoi vous voudriez le faire en premier lieu. Le problème est que vous pourriez avoir un code AngularJS qui repose sur les plugins Cordova/PhoneGap/Ionic, et que ces plugins ne seront prêts qu'après le démarrage d'AngularJS car Cordova prend plus de temps à fonctionner sur un périphérique que le code Javascript ordinaire. pour AngularJS fait.

Donc, dans ces cas, nous devons attendre que Cordova/PhoneGap/Ionic soit prêt avant de démarrer (démarrer) AngularJS afin que Angular ait tout ce dont il a besoin pour fonctionner.

Par exemple, supposons que vous utilisez le module NG-Persist Angular), qui utilise le stockage local pour enregistrer les données sur un navigateur, plug-in iOS Keychain lors de l'exécution sur iOS, et le cordova-plugin-file lors de l'exécution sur Android. Si votre Angular) tente de charger/enregistrer quelque chose d'emblée , La vérification de NG-Persist sur window.device.platform (à partir du plugin ) échouera car le code mobile n'a pas encore été démarré et vous n'aurez qu'une page blanche à la place de votre jolie application.

68
Michael Oryl

Si vous utilisez Ionic , cette solution fonctionne pour les navigateurs et les appareils. Crédit à romgar sur ce fil .

window.ionic.Platform.ready(function() {
    angular.bootstrap(document, ['<your_main_app']);
});

Vous devez toujours supprimer ng-app de votre élément DOM.

32
Wade Anderson

Cette solution est devenue plus robuste lorsque j'ai utilisé:

angular.element(document).ready(function () {
  var domElement = document.getElementById('appElement');
  angular.bootstrap(domElement, ["angularAppName"]);
});

MISE À JOUR

Ma suggestion était de mettre ce qui précède dans la fonction appropriée de la fonction, par exemple:

document.addEventListener("deviceready", function() {
    angular.element(document).ready(function () {
      var domElement = document.getElementById('appElement');
      angular.bootstrap(domElement, ["angularAppName"]);
    });
}, false);
5
levsa

En utilisant la solution de TheHippo:

document.addEventListener("deviceready", function() {
    // retrieve the DOM element that had the ng-app attribute
    var domElement = document.getElementById(...) / document.querySelector(...);
    angular.bootstrap(domElement, ["angularAppName"]);
}, false);

Cela ne fonctionne pas dans le navigateur, car "cordova.js" est résolu par le processus de construction de Cordova ou Phonegap et n'est pas disponible dans votre environnement de test localhost ou émulé.

Ainsi, l'événement "deviceready" n'est jamais déclenché. Vous pouvez simplement le déclencher manuellement dans la console de votre navigateur.

var customDeviceReadyEvent = new Event('deviceready');
document.dispatchEvent(customDeviceReadyEvent);

Assurez-vous également que le bootstrap de angular est activé) après vous avoir tous défini angular modules/contrôleurs/usines/directives etc.

2
devjsp

Dans la plupart des cas, vous n'avez probablement pas besoin de bloquer le chargement de votre angular angulaire jusqu'à ce que deviceready devienne (rappelez-vous que cela peut prendre plusieurs secondes pour que la diélectrique se déclenche si vous avez beaucoup de plugins).

Au lieu de cela, vous pouvez utiliser quelque chose comme cette bibliothèque ( https://github.com/arnesson/angular-cordova ) qui résout les problèmes de périphériques en plaçant automatiquement en mémoire tampon les appels, puis en les exécutant après le déclenchement de deviceready. .

0
ropsnou