Cordova + Angularjs + Device Ready

57

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


请查看这个 Angular 2 的解决方案:https://dev59.com/8aLia4cB1Zd3GeqPg0kW#44397322 - Amir
6个回答

87

手动引导您的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);

Angular应用程序启动的文档。


1
设备准备就绪事件(deviceready)是否总是在文档准备就绪事件(documentready)之后触发?如果不是,那么有时它将无法正常工作。 - olanod
4
如果应用程序在没有Cordova的浏览器中运行,这种方法将不起作用。我的解决方案如下解决了这个问题。 - Michael Oryl
如 @wade-anderson 所答,window.ionic.Platform.ready() 怎么样? - levsa

69
我正在使用以下解决方案,它允许在 Cordova 中运行时引导 AngularJS,以及在直接在浏览器中运行时引导,这是我大部分开发工作的地方。您必须从主 index.html 页面中删除 ng-app 指令,因为手动引导正在替换它。
更新:我已经切换到以下方法,我认为更加简洁。它适用于 Ionic 以及原始的 Cordova/PhoneGap。它应该是最后要运行的 JavaScript 代码块 - 可能在 /body 标签之前的

1
为了能够在浏览器中进行测试,我通常会创建一个假的cordova.js文件,其中包含一些代码,例如自动调用任何已注册的“deviceready”事件。 - user276648
@user276648,你能分享一下你的假Cordova.js代码(例如Github Gist)吗? - hgoebl
1
如果我这样做,就会出现“未捕获的错误:[$injector:modulerr]无法实例化模块应用程序,原因是: 错误:[$injector:nomod]模块'app'不可用!您可能拼写错误了模块名称或忘记加载它。如果要注册模块,请确保将依赖项指定为第二个参数。”我该怎么办? - Ken Vernaillen
3
我猜测你的主应用程序模块不叫做 app,就像我的示例一样。请查看两个 angular.bootstrap(document.body, ['app']); 行,并将其更改为你的应用程序中的主要模块名称。如果这对你有用,请不要忘记给它投票。 - Michael Oryl
这意味着我在个别插件调用中不再需要包装设备就绪吗? - konzo

32
如果您正在使用Ionic,则此解决方案适用于浏览器和设备。感谢romgar在此thread中的贡献。
window.ionic.Platform.ready(function() {
    angular.bootstrap(document, ['<your_main_app']);
});

仍需从您的DOM元素中删除ng-app。


1
这非常棒。 - Kenny Ki
这只适用于使用 Ionic(在提问时不存在)的情况。仍然有开发人员在使用 Cordova 和 Angular 而没有使用 Ionic。 - TheHippo
@TheHippo 谢谢您先生。我错过了那个。我已经编辑了我的答案,包括您正在使用Ionic的规定。 - Wade Anderson
你能提供一个完整的例子吗?我无法让它工作。这段代码放在angular.module.run、$ionicPlatform.ready中还是放在外面? - Carlos Goce
1
@CarlosGoce 代码片段不应该在Angular内运行。它应该在HTML页面底部以纯Javascript方式执行。如果您的HTML中有ng-app属性,请勿删除它 - 它的功能将由上述片段引导Angular取代。 - j7m
显示剩余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);

2
如果您在代码的早期使用任何 Cordova 特定函数,可能会出现这些函数尚未准备好的情况。因此,documentReady != deviceready - TheHippo
那应该放在deviceready处理程序中,并且是从引导文档中获取的。 - levsa
1
我不理解为什么会被踩。我的建议来自于Bootstrap文档,并且完整的代码如下(对我来说运行良好):document.addEventListener("deviceready", function() { angular.element(document).ready(function () { // retrieve the DOM element that had the ng-app attribute var domElement = document.getElementById('appElement'); angular.bootstrap(domElement, ["angularAppName"]); }); }, false); - levsa
你已经成功地钩取了Angular/Bootstrap的ready函数,但没有钩取Cordova的deviceready事件,这正是帖子中提到的问题。 - Chris Rae
我正在尝试同时进行_deviceready_和_document ready_,因为Angular文档建议在调用angular.bootstrap()之前使用angular.element(document).ready()。但是,如果window.ionic.Platform.ready()(或document.addEventListener("deviceready", ...))总是意味着_document ready_,那么它就不需要了。 - levsa
显示剩余3条评论

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

因为"Cordova.js"会在Cordova或Phonegap的构建过程中被解析,而在本地主机或模拟测试环境中不可用,所以它无法在浏览器中运行。

因此,“deviceready”事件永远不会被触发。您可以在浏览器控制台中手动触发它。

var customDeviceReadyEvent = new Event('deviceready');
document.dispatchEvent(customDeviceReadyEvent);

同时确保在设置所有的angular模块/控制器/工厂/指令等之后,触发angular的引导程序。


0
在大多数情况下,您可能不需要阻止加载您的Angular应用程序直到deviceready之后(请注意,如果您有很多插件,则可能需要几秒钟才能触发deviceready)。
相反,您可以使用类似于这个库(https://github.com/arnesson/angular-cordova),它可以通过自动缓冲调用并在deviceready被触发后执行它们来解决deviceready问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接