【问题标题】:Detect if Angular dependencies [angular-route, angular-resource, etc] are loaded for CDN fallback检测是否为 CDN 回退加载了 Angular 依赖项 [角度路由、角度资源等]
【发布时间】:2013-09-14 22:12:21
【问题描述】:

我在 ASP.NET MVC 4 上使用 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.Angular 很容易检测 jQuery 或 AngularJS 是否存在。 ASP.NET 捆绑机制评估 CdnFallbackExpression 文本以查看它是否需要回退到源服务器。

但是,在更高版本的 AngularJS 中,其他模块(例如 ngRoute 和 ngResource)被分离到自己的文件中,由开发人员自行决定加载。

如何检测是否加载了其他 AngularJS 模块?我可以在控制台输入什么来查看 ngAnimate、ngRoute、ngResource 等是否成功从 CDN 加载?

【问题讨论】:

  • 也许angular.module('moduleName') 有效。如果模块不存在,它可能会抛出异常,但我不确定这是否是正确的做法。
  • @gustavohenke 我在玩这个,但你是对的,喷油器生气了。很生气。
  • 如果你可以把它包装在一个try..catch 块中,也许就是这样:)
  • 使用 require.js 和 Angular 加载器

标签: javascript angularjs cdn fallback


【解决方案1】:

这是我用的:

<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 在这里很棒。

【讨论】:

    【解决方案2】:

    这是一种特别适用于您在 OP 中提供的 Microsoft 优化框架的方法

    angularjsRoute.CdnFallbackExpression = @"
        function() { 
            try { 
                window.angular.module('ngRoute');
            } catch(e) {
                return false;
            } 
            return true;
        })(";
    

    此表达式本身不是有效的 javascript,但 MS 优化框架使用此表达式并最终向页面生成以下输出。现在我们有了一个有效的自执行 javascript 函数,它根据 Angular 模块是否加载返回 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>
    

    【讨论】:

    • 您作为编译版本的声明也不是有效的javascript,Chrome中的控制台也不可能。
    【解决方案3】:

    (来自 qntmfred 的答案的变化。)

    不要留下那个奇怪的尾随左括号,只需使用一个普通的立即调用函数。

    结果将只是优化框架将其包装在另一组括号中,但使您的 C# 更加清晰。

    angularjsRoute.CdnFallbackExpression = 
        @"(function() { 
            try { 
                window.angular.module('ngRoute');
            } catch(e) {
                return false;
            } 
            return true;
        })()";
    

    【讨论】:

      【解决方案4】:

      另一种变化...

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-08
        • 1970-01-01
        • 2018-11-07
        相关资源
        最近更新 更多