我正在使用Cordova 3.3.1-0.4.2和Angular 1.2.13
收到Cordova“ deviceready”事件后,我需要手动引导Angular。
我正在Nexus 5上进行测试,cordova run android但在iPhone上却具有完全相同的行为。
cordova run android
为了简化问题,这是JS在全局文档范围内运行。脚本在结束</body>标记之前加载。
</body>
这有效:
angular.bootstrap(document.getElementById("app"), ["MyApp"]);
这不起作用:
function init(){ angular.bootstrap(document.getElementById("app"), ["MyApp"]); } document.addEventListener('deviceready', function () { init(); }, true);
但是,如果我添加alert("init")到显示它正在运行的init方法中。同时alert(angle)和alert(document.getElementById(“ app”))表示它们存在。
alert("init")
我不明白为什么,由于调用了init(),因此从EventListener回调中调用它时不起作用,但是如果直接调用它,则它确实起作用。
看起来很奇怪/直觉。
任何人?
我发现的最佳解决方案是正常启动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); } ); } ]);
我在GitHub上分享了这个引导项目