从Cordova deviceready事件手动引导AngularJS

时间:2014-02-18 00:52:17

标签: javascript angularjs cordova addeventlistener

我正在使用Cordova 3.3.1-0.4.2和Angular 1.2.13

一旦我收到Cordova'deviceready'事件,我需要手动引导Angular。

我正在使用cordova run android在Nexus 5上进行测试,但在iPhone上的行为完全相同。

为简化问题,这是JS在全局文档范围内运行。在结束</body>标记之前加载脚本。


这有效:

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

这不起作用:

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

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

但是,如果我将alert("init")添加到显示它正在运行的init方法中。警报(角度)和警报(document.getElementById(“app”))也表明它们存在。

我不明白为什么,假设正在调用init(),它在从EventListener回调调用时不起作用,但如果直接调用它确实有效。

似乎很奇怪/不直观。

任何?

3 个答案:

答案 0 :(得分:4)

我发现的最佳解决方案是正常引导Angular,然后将Cordova作为一个返回promise的模块加载,该模式在设备准备就绪时解析。

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);
    });  
  }
]);

用法:

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);
      }
    );
  }
]);

我已经分享了这个引导项目here on GitHub

答案 1 :(得分:1)

对于那些在cordova deviceready事件之后真正想要手动提升angularjs的人应该使用它。你也可以在这里阅读它的详细信息AngularJS + Cordova (Updated And Even Better!)

'use strict';

var CordovaInit = function() {

var onDeviceReady = function() {
    receivedEvent('deviceready');
};

var receivedEvent = function(event) {
    console.log('Start event received, bootstrapping application setup.');
    angular.bootstrap($('body'), ['c3aApp']); // Manually add and boot Angularjs 
};

this.bindEvents = function() {
    document.addEventListener('deviceready', onDeviceReady, false);
};

//If cordova is present, wait for it to initialize, otherwise just try to
//bootstrap the application.
if (window.cordova !== undefined) {
    console.log('Cordova found, wating for device.');
    this.bindEvents();
} else {
    console.log('Cordova not found, booting application');
    receivedEvent('manual')
}
};

$(function() {
console.log('Bootstrapping!');
new CordovaInit();
});

我个人选择了这种方法,因为我需要在Angularjs加载之前从设备上获取一些来自Angularjs配置的SQlite数据库,并且首先加载Angularjs似乎会破坏我的代码。

我一直在使用这种方法,一切都很顺利。

//请检查您的.js文件的顺序。

答案 2 :(得分:0)

  1. 根据Cordova deviceready文档,您应该附加到onLoad事件中的deviceready事件
  2. 你可能会遇到一个javascript库订购问题
  3. 我发布了我提出的解决方案的大纲,该解决方案不需要通过promises进行延迟初始化,并且经过测试,可以在多个仿真器和物理iOS和Android设备on my blog上运行可靠性。