Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
403 views
in Technique[技术] by (71.8m points)

javascript - Manually bootstrapping AngularJS from Cordova deviceready event

I'm using Cordova 3.3.1-0.4.2 and Angular 1.2.13

I need to manually bootstrap Angular once I get the Cordova 'deviceready' event.

I'm testing on a Nexus 5 with cordova run android but am having exactly the same behaviour on an iPhone.

To simplify the problem this is JS running in the global document scope. Scripts are being loaded before the closing </body> tag.


This works:

angular.bootstrap(document.getElementById("app"), ["MyApp"]);

This doesn't work:

function init(){
  angular.bootstrap(document.getElementById("app"), ["MyApp"]);
}

document.addEventListener('deviceready', function () {
  init();
}, true);

However if I add alert("init") to the init method that shows it IS running. Also alert(angular) and alert(document.getElementById("app")) show that they exist.

I don't understand why, given that init() is being called, it doesn't work when called from the EventListener callback yet it does work if called directly.

Seems weird / unintuitive.

Anyone?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The best solution I've found is to bootstrap Angular as normal and then load Cordova as a module that returns a promise, which is resolved when the device is ready.

angular.module('fsCordova', [])
.service('CordovaService', ['$document', '$timeout', '$window',  '$q',
  function($document, $timeout, $window, $q) {

    var defer = $q.defer();

    this.ready = defer.promise;

    // Backup in the case that we did not received the event
    // This seemed to be necessary with some versions of Cordova
    // when testing via 'cordova serve' in a web browser
    // but when on-device the event is received correctly
    var timoutPromise = $timeout(function() {
      if ($window.cordova){
        defer.resolve($window.cordova);
      } else {
        defer.reject("Cordova failed to load");
      }     
    }, 1200);

    angular.element($document)[0].addEventListener('deviceready', function() {
      $timeout.cancel(timoutPromise);
      defer.resolve($window.cordova);
    });  
  }
]);

Usage:

angular.module('app', ['fsCordova']).

run(['$window', function($window){
  // init Fastclick
  FastClick.attach(angular.element($window.document.body)[0]);
}]).

controller('AppCtrl', ['$scope', 'CordovaService', 
  function($scope, CordovaService){

    $scope.ready = false;

    // when cordova is ready
    CordovaService.ready.then(
      function resolved(resp) {
         $scope.ready = true;  
      },
      function rejected(resp){
        throw new Error(resp);
      }
    );
  }
]);

I've shared this bootstrap project here on GitHub


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...