我正在使用Cordova和AngularJS开发移动应用程序。如何在Cordova设备准备好之前限制AngluarJS的引导。基本上我不想在设备就绪之前使用任何AngularJS控制器。
答案 0 :(得分:83)
手动引导你的Angular应用程序:
从HTML代码中删除ng-app
属性,因此Angular不会自行启动。
将类似内容添加到JavaScript代码中:
document.addEventListener("deviceready", function() {
// retrieve the DOM element that had the ng-app attribute
var domElement = document.getElementById(...) / document.querySelector(...);
angular.bootstrap(domElement, ["angularAppName"]);
}, false);
bootstrapping个应用的角度文档。
答案 1 :(得分:68)
我使用以下解决方案,允许在使用Cordova时运行AngularJS以及在浏览器中直接运行时 ,这是我开发的大部分内容。您必须从主index.html页面中删除ng-app指令,因为手动引导正在替换它。
更新:我已经切换到以下方法,我认为这个方法比较清晰。它适用于Ionic以及香草Cordova / PhoneGap。它应该是JavaScript的最后一点 - 可能在 / body 标记之前的脚本标记内。
angular.element(document).ready(function () {
if (window.cordova) {
console.log("Running in Cordova, will bootstrap AngularJS once 'deviceready' event fires.");
document.addEventListener('deviceready', function () {
console.log("Deviceready event has fired, bootstrapping AngularJS.");
angular.bootstrap(document.body, ['app']);
}, false);
} else {
console.log("Running in browser, bootstrapping AngularJS now.");
angular.bootstrap(document.body, ['app']);
}
});
这是我使用的旧解决方案:
// This is a function that bootstraps AngularJS, which is called from later code
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This is my preferred Cordova detection method, as it doesn't require updating.
if (document.URL.indexOf( 'http://' ) === -1
&& document.URL.indexOf( 'https://' ) === -1) {
console.log("URL: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("URL: Running in browser");
bootstrapAngular();
}
如果您遇到http / https检测方法的问题,或许是因为将Cordova应用程序从网络加载到手机中,您可以使用以下方法:
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This method of user agent detection also works, though it means you might have to maintain this UA list
if (navigator.userAgent.match(/(iOS|iPhone|iPod|iPad|Android|BlackBerry)/)) {
console.log("UA: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("UA: Running in browser");
bootstrapAngular();
}
请注意,您仍需要第一个示例中的相同bootstrapAngular函数。
为什么使用Cordova / PhoneGap / Ionic手动引导AngularJS?
有些人来到这里可能不知道你为什么要这样做。问题是你可以使用依赖于Cordova / PhoneGap / Ionic插件的AngularJS代码,这些插件在AngularJS启动之前就已经准备就绪,因为Cordova需要更长的时间来启动和运行设备而不是普通的AngularJS的Javascript代码可以。
因此,在这些情况下,我们必须等到Cordova / PhoneGap / Ionic准备就绪,然后才能启动(引导)AngularJS,以便Angular拥有运行所需的一切。
例如,假设您使用的是NG-Persist Angular模块,该模块使用本地存储在浏览器上保存数据,在iOS上运行时iOS Keychain plugin,以及cordova-plugin-file时在Android上运行。如果您的Angular应用程序尝试立即加载/保存某些内容,则NG-Persist对window.device.platform(来自device plugin)的检查将失败,因为移动代码尚未完成启动时,你只会得到一个白页,而不是你漂亮的应用程序。
答案 2 :(得分:32)
如果您使用的是Ionic,则此解决方案适用于浏览器和设备。感谢此romgar上的thread。
window.ionic.Platform.ready(function() {
angular.bootstrap(document, ['<your_main_app']);
});
仍需要从DOM元素中删除ng-app。
答案 3 :(得分:5)
使用时,此解决方案变得更加强大:
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
<强>更新强>
我的建议是将上述内容放在适当的deviceready函数中,例如:
document.addEventListener("deviceready", function() {
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
}, false);
答案 4 :(得分:2)
使用TheHippo的解决方案:
document.addEventListener("deviceready", function() { // retrieve the DOM element that had the ng-app attribute var domElement = document.getElementById(...) / document.querySelector(...); angular.bootstrap(domElement, ["angularAppName"]); }, false);
它不能在浏览器中工作,因为&#34; cordova.js&#34;通过Cordova或Phonegap构建过程解决,并且在您的localhost或模拟测试环境中不可用。
因此&#34; deviceready&#34;事件永远不会被解雇您只需在浏览器控制台中手动触发即可。
var customDeviceReadyEvent = new Event('deviceready');
document.dispatchEvent(customDeviceReadyEvent);
还要确保在设置所有角度模块/控制器/工厂/指令等后触发角度引导。
答案 5 :(得分:0)
在大多数情况下,您可能不需要在设备准备之后阻止加载角度应用程序(请注意,如果您有大量插件,可能需要几秒钟才能启动设备)。
相反,您可以使用类似lib(https://github.com/arnesson/angular-cordova)之类的东西,它可以通过自动缓冲调用来解决设备问题,然后在触发设备之后执行它们。