从 Cordova deviceready 事件手动引导 AngularJS [英] Manually bootstrapping AngularJS from Cordova deviceready event

查看:29
本文介绍了从 Cordova deviceready 事件手动引导 AngularJS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Cordova 3.3.1-0.4.2 和 Angular 1.2.13

I'm using Cordova 3.3.1-0.4.2 and Angular 1.2.13

我需要在收到 Cordova 'deviceready' 事件后手动引导 Angular.

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

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

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

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

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

这有效:

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

这不起作用:

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

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

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

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.

我不明白为什么,鉴于正在调用 init(),它在从 EventListener 回调中调用时不起作用,但如果直接调用它却起作用.

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.

有人吗?

推荐答案

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

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

用法:

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

我在 GitHub 上分享了这个引导项目这里

I've shared this bootstrap project here on GitHub

这篇关于从 Cordova deviceready 事件手动引导 AngularJS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆