Cordova + Angularjs +设备就绪

时间:2014-02-04 15:09:29

标签: angularjs cordova angularjs-service

我正在使用Cordova和AngularJS开发移动应用程序。如何在Cordova设备准备好之前限制AngluarJS的引导。基本上我不想在设备就绪之前使用任何AngularJS控制器。

6 个答案:

答案 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)之类的东西,它可以通过自动缓冲调用来解决设备问题,然后在触发设备之后执行它们。