我正在使用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回调调用时不起作用,但如果直接调用它确实有效。
似乎很奇怪/不直观。
任何?
答案 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)
我发布了我提出的解决方案的大纲,该解决方案不需要通过promises进行延迟初始化,并且经过测试,可以在多个仿真器和物理iOS和Android设备on my blog上运行可靠性。