我在 MVC 4 ASP.NET 上使用 Angular JS,我正在使用脚本包从 cdn 加载,并在发生 cdn 故障时从源服务器加载,如下所示:
var jQuery = new ScriptBundle("~/bundles/scripts/jquery",
"//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js") // CDN
.Include("~/Scripts/jquery-{version}.js"); // Local fallback
jQuery.CdnFallbackExpression = "window.jQuery"; // Test existence
bundles.Add(jQuery);
和
var angular = new ScriptBundle("~/bundles/scripts/angular",
"//ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.min.js")
.Include("~/Scripts/angular.js");
angular.CdnFallbackExpression = "window.angular";
bundles.Add(angular);
使用window.jQuery和window检测jQuery或AngularJS是否存在是相当容易的。分别是有角度的。 ASP.NET 捆绑机制评估 CdnFallbackExpression 文本,以查看它是否需要回退到源服务器。
但是,在更高版本的AngularJS中,其他模块(如ngRoute和ngResource)被分离到自己的文件中,由开发人员自行决定加载。
如何检测是否加载了其他 AngularJS 模块?我可以在控制台中键入什么来查看ngAnimate,ngRoute,ngResource等是否成功从CDN加载?
这是一种专门适用于您在 OP 中提供的Microsoft优化框架
的方法angularjsRoute.CdnFallbackExpression = @"
function() {
try {
window.angular.module('ngRoute');
} catch(e) {
return false;
}
return true;
})(";
此表达式本身不是有效的 javascript,但 MS 优化框架使用它并最终生成以下输出到页面。现在我们有一个有效的自执行 javascript 函数,它根据角度模块是否加载返回 true 或 false。
<script>(
function() {
try {
window.angular.module('ngRoute');
}
catch(e) {
return false;
}
return true;
})()||document.write('<script src="/bundles/scripts/angularjs-route"></script>');</script>
使用的:
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.5.0/ui-bootstrap.min.js"></script>
<script>
try { //try to load from cdn
//use the name of the angular module here
angular.module('ui.bootstrap');
}
catch(e) { //error thrown, so the module wasn't loaded from cdn
//write into document from local source
document.write('<script src="sys/lib/ui-bootstrap.js"></script>');
}
</script>
如果没有这样的模块,angular.module
会抛出错误,这正是我们需要知道的! try/catch
在这里很棒。
(来自qntmfred的答案的变化。
与其留下那个奇怪的尾随开括号,不如使用一个正常的立即调用的函数。
结果只是优化框架会将其包装在另一组括号中,但会使 C# 更加清晰。
angularjsRoute.CdnFallbackExpression =
@"(function() {
try {
window.angular.module('ngRoute');
} catch(e) {
return false;
}
return true;
})()";
另一种变体...
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script>
<script>
try {
window.angular.module('ui.bootstrap');
}
catch(e) {
var script = document.createElement('script');
script.src = 'lib/bootstrap/dist/js/bootstrap.js';
document.getElementsByTagName('head')[0].appendChild(script);
}
</script>