admin管理员组

文章数量:1323330

I'm having issues getting 'deviceready' to register from inside of AngularJS. I'm certain this was working before, so I'm not sure what's changed.

If I call 'deviceready' from a global addEventListener, it works, like so:

document.addEventListener('deviceready', function(){
   localStorage.deviceReadyGlobal = true;
});

deviceReadyGlobal=true is set. However, if I try to attach this from within Angular, it never fires, like so:

app.run(function(){
    document.addEventListener('deviceready', function(){
        localStorage.deviceReadyAngular = true;
    });
});

deviceReadyAngular is never set. Now, I understand that PhoneGap probably already fired 'deviceready' while Angular was bootstrapping, but according to the PhoneGap docs, that shouldn't matter.

The deviceready event behaves somewhat differently from others. Any event handler registered after the deviceready event fires has its callback function called immediately.

Did something change in the behavior of 'deviceready'?

I'm using Cordova 3.3.0 and Angular 1.2.5 currently.

I'm having issues getting 'deviceready' to register from inside of AngularJS. I'm certain this was working before, so I'm not sure what's changed.

If I call 'deviceready' from a global addEventListener, it works, like so:

document.addEventListener('deviceready', function(){
   localStorage.deviceReadyGlobal = true;
});

deviceReadyGlobal=true is set. However, if I try to attach this from within Angular, it never fires, like so:

app.run(function(){
    document.addEventListener('deviceready', function(){
        localStorage.deviceReadyAngular = true;
    });
});

deviceReadyAngular is never set. Now, I understand that PhoneGap probably already fired 'deviceready' while Angular was bootstrapping, but according to the PhoneGap docs, that shouldn't matter.

The deviceready event behaves somewhat differently from others. Any event handler registered after the deviceready event fires has its callback function called immediately.

Did something change in the behavior of 'deviceready'?

I'm using Cordova 3.3.0 and Angular 1.2.5 currently.

Share edited Dec 20, 2013 at 0:26 Jason Farnsworth asked Dec 19, 2013 at 21:39 Jason FarnsworthJason Farnsworth 8049 silver badges15 bronze badges 6
  • 1 Not sure why it's not working, but I've always just bootstrapped angular in deviceReady handler. – Jonathan Rowny Commented Dec 19, 2013 at 21:51
  • Thanks. I know that many PhoneGap/Angular people remend that approach. I'm trying to avoid it, since we don't have any blocking PhoneGap dependencies in our app bootstrap. We also don't /always/ run the app in PhoneGap. – Jason Farnsworth Commented Dec 19, 2013 at 22:22
  • 1 I'll bet you're missing the deviceready event by attaching your handler too late. Have you tried using a global to catch it before angular starts, and then adding the event in your run block only if you haven't already seen the event? – Jeff Hubbard Commented Dec 20, 2013 at 7:58
  • @JeffHubbard cordova.js hijacks document.addEventListener and modifies it so that it executes the callback function immediately if you try to attach 'deviceready' after it's already fired once. So, it should handle this case properly. I think I have a partial answer though - I'll be writing it up a bit later. Thanks! – Jason Farnsworth Commented Dec 20, 2013 at 22:47
  • 1 @sandstrom Not entirely. I seemed to have two issues. If I used on(), then PhoneGap and Angular seemed to have a conflict with their event handler hijacking. If I used addEventListener(), it just seemed like Angular was executing before cordova.js was loaded. Either way it was fickle, and I ended up moving that code out of Angular. I'm just running it in it's own global namespace now. – Jason Farnsworth Commented Jan 15, 2014 at 23:34
 |  Show 1 more ment

3 Answers 3

Reset to default 5

This is how I do it inside my app;

// Create an application module with dependencies
var app = angular.module('myApp', []);

function loadTheApp() {

    // Hide splash screen if any
    if (navigator && navigator.splashscreen) {
        navigator.splashscreen.hide();
    }

    // Initiate FastClick
    FastClick.attach(document.body);

    // Boot AngularJS
    try {
        angular.bootstrap(document, ['myApp']);
    } catch (e) {
        console.log('errrrrrrrrrrrrrr! ' + e);
    }
}

// Listen to device ready
angular.element(document).ready(function() {
    if (window.cordova) {
        document.addEventListener('deviceready', loadTheApp, false);
    } else {
        loadTheApp();
    }
});

This way if we are inside a device environement then we listen to deviceready event, if not, then we just ignore that event and load our app.

Either way you could also handle it with DOMContentLoaded event handler in javascript way

document.addEventListener("DOMContentLoaded", function() {
    //alert("Calling DOMContentLoaded");
    document.addEventListener('deviceready', function(){
        //alert("Calling onDeviceReady()");
        initializeYourApp();
    }, false);
});

I've had this issue. For me the problem was having the for cordova.js inside the header.

If you generate a sample project from cordova cli, they have the script tag inside the body.

Once i put it in the body ,like the sample project had it, next to the app-root, i started getting the deviceready event

本文标签: javascriptCordova 39deviceready39 event not firing from within angular run blockStack Overflow