=== TL; DR ===
简短版本(相信我,我整天都在研究这个问题):
我有一个很大的脚本列表,包括角度和非角度 东西(1.2.x)。当我尝试使用LAB.js加载它时,包括 AlwaysPreserveOrder标志,Angular太火了。挖掘,它 似乎Angular正在使用$(document).ready(/ * start angular * /)。 可理解的,脚本加载器破坏了正常的文档 事件
所以,我尝试使用$ .holdReady(true)和$ .holdReady(false),但是,我得到了 真奇怪的行为:虽然$ .holdReady(true)确实增加了 $ .readyWait按预期,它只是不会阻止角度 初始化......最重要的是,如果我尝试设置自己的监听器 对于$(document).ready(),它永远不会触发,即使有角度 似乎正在利用同样的事件开火...
...为了增添神秘色彩,每一次在蓝色的月亮中,如果我把它设置为 继续执行window.location.reload()失败,直到工作完成为止 实际上只会工作 - 很少。这使它看起来像一场比赛 条件,但鉴于我传递了订单标志,我不能 想象什么会比赛,这个线索似乎也不适合 其他一切,据我所知......
请注意,如果我切换到该文件的非lab.js版本,那就是一切 似乎工作得很好,包括$ .readyWait计数,一切 (包括角度)等待$ .holdReady(false)被调用, $(document).ready()我自己解雇的标志等等。
====== LONG VERSION ======
我试图制作一个最不可行的例子,但现实世界的工作代码更加复杂available here,而破坏的版本是available here - 他们是仍然清理尽可能使问题尽可能明显,而不会消除任何潜在的混淆因素。
这有效:
<body ng-app="mapmycustomersApp" ng-strict-di>
<script src="build/libraries/LAB.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.min.js"></script>
<script src="https://code.angularjs.org/1.2.32/angular-resource.min.js"></script>
<script src="https://code.angularjs.org/1.2.32/angular-route.min.js"></script>
<script>
document.write('<script src="build/app.js"></script>')
document.write('<script src="build/controllers/main.js"></script>')
</script>
</body>
这不是:
<body ng-app="mapmycustomersApp" ng-strict-di>
<script src="build/libraries/LAB.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.min.js"></script>
<script src="https://code.angularjs.org/1.2.32/angular-resource.min.js"></script>
<script src="https://code.angularjs.org/1.2.32/angular-route.min.js"></script>
<script>
$LAB.setGlobalDefaults({ AlwaysPreserveOrder: true });
$LAB
.script("build/app.js")
.script("build/controllers/main.js")
</script>
</body>
这两点都没有:
<body ng-app="mapmycustomersApp" ng-strict-di>
<script src="build/libraries/LAB.min.js"></script>
<script>
$LAB.setGlobalDefaults({ AlwaysPreserveOrder: true });
$LAB
.script("https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.min.js")
.script("https://code.angularjs.org/1.2.32/angular-resource.min.js")
.script("https://code.angularjs.org/1.2.32/angular-route.min.js")
.script("build/app.js")
.script("build/controllers/main.js")
</script>
</body>
第三个(上一个)是我真正想要的。
他们生成this error:
模块&#39; mapmycustomersApp&#39;不可用!你要么拼错了 模块名称或忘记加载它。如果注册模块,请确保 您将依赖项指定为第二个参数。
在写这个答案时,我取得了一些进展,但遇到了一个新的死胡同,我发誓感觉就像是jquery或angular中的一个bug。
为什么呢?我可以跟踪它的最后面的部分告诉我,即使应用程序注册自己之前,angularInit()的调用太快了...... 在角度文件的底部调用,在第2232行:
jqLite(document).ready(function() {
angularInit(document, bootstrap);
});
jqLite设置为jQuery(我通过检查angular.element === $确认了这一点,这是真的,这在角度代码的其他地方得到证明)。 所以这应该只是在$(document).ready()上触发。 哪个已知加载器问题。 这就是他们创建$ .holdReady()的原因。
但出于某种原因,这对我不起作用。 我得到非常奇怪的输出。
这就是我的意思:
如果我将jquery脚本标记(2.2.4)移动到头顶部,然后在其下方调用$.holdReady(true)
,我可以看到$.readyWait
递增。 (我甚至可以称它为好几次,并观察它最多四次。)
然后我在.wait(() => $.readyWait(false))
次调用结束时粘贴了.script()
...但如果我在此之前安装了console.log,我可以看到它从中删除,比方说,已经4
到0
,意味着准备已经解雇了。 $.readyWait()
什么也没做。
有价值的线索
很少,非工作代码有效......然后在刷新时再次失败,没有任何变化。这似乎表明了竞争条件,但我无法理解那将是什么,而且我不会与我所见过的其他情况对齐......然而,它发生了。 在这些时候,$ .readyWait返回1而不是0 。
我知道这很多,但我觉得这里完全不知所措。世界上到底发生了什么?
哦,还有一个让我感到困惑的非常重要的线索:$(document).ready(_ => console.log("I loaded"))
永远不会运行。 $(window).load
,否则相同,运行正常。在我宣布那个听众的地方并不重要,它永远不会为我开火,即使我把听众置于页面的顶部......然而它显然会以某种方式触发,因为它触发了什么{ {1}}!我的理解是,如果我打电话就应该开火,即使它已经被解雇了!
...只是为了表明我没有犯下一些非常明显的错误,所有相同的代码都会按预期触发(angularInit
事件,而document ready
两者都完全符合您的要求#&# 39; d expect)每当我切换到所有脚本标签时。
在代码中:
holdReady()
(详见:
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script>
$(window).load(function() {
console.log("this fires");
});
$(document).ready(function() {
console.log("this doesn't");
debugger;
});
console.log("holding ready", $.readyWait);
$.holdReady(true);$.holdReady(true);$.holdReady(true); // needed because we use LAB.js, which messes with Document.ready, which Angular depends on
console.log('rw, ', $.readyWait)
</script>
包括
app.js
和var app = angular.module('mapmycustomersApp' ['ngRoute','ui.bootstrap','ngStorage','ngFileUpload'])
.config(['$routeProvider', '$locationProvider', '$compileProvider', function($routeProvider, $locationProvider, $compileProvider) { // ...
包括
main.js
所有代码都是有用的,我只是想把所有代码都移到LAB.js上,发现自己无法做到。其他评论:切换到角度1.6.4只是为了好玩没有效果(除了完全没有加载完成那些罕见的成功,因为$ http()。成功不是一个函数,所以他们必须在更高版本中更改该API) ,我们在版本2中使用最新版本的jquery,切换到3+会引发其他不兼容错误。
答案 0 :(得分:0)
我在确定问题时是正确的。在与Kyle Simpson的长时间讨论中,他指出在角度1.2x源代码中使用$.ready
是基于错误假设的常见错误,这使得加载javascript源异步不可行。
出于某种原因,使用$.holdReady()
最终确实有效。我不确定为什么它没有,但我怀疑我不小心包括了两次jquery依赖,覆盖了之前的readyCount。