Подтвердить что ты не робот

Обнаруживать, если для резервной копии CDN загружены Angular зависимости [angular -route, angular -resource и т.д.]

Я использую Angular JS на ASP.NET MVC 4, и я использую пакеты script для загрузки из 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);

Довольно легко обнаружить, существуют ли jQuery или AngularJS с помощью window.jQuery и window.Angular соответственно. Механизм связывания ASP.NET оценивает текст CdnFallbackExpression, чтобы увидеть, нужно ли ему возвращаться к исходному серверу.

Однако в более поздних версиях AngularJS другие модули, такие как ngRoute и ngResource, разделяются на свои собственные файлы, которые должны быть загружены по усмотрению разработчиков.

Как определить, загружены ли другие модули AngularJS? Что я могу ввести в консоль, чтобы проверить, удалось ли ngAnimate, ngRoute, ngResource и т.д. Загрузиться с CDN?

4b9b3361

Ответ 1

Вот подход, который работает специально с Microsoft Optimization Framework, как вы указали в OP

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

Это выражение недействительно javascript, но платформа оптимизации MS использует это и в конечном итоге производит следующий вывод на страницу. Теперь у нас есть действующая самозавершаемая функция javascript, которая возвращает true или false на основании того, загружен ли модуль angular.

<script>(
function() { 
    try {
        window.angular.module('ngRoute');
    }
    catch(e) {
        return false;
    }

    return true;
})()||document.write('<script src="/bundles/scripts/angularjs-route"><\/script>');</script>

Ответ 2

Это то, что я использую:

<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 здесь отлично.

Ответ 3

(Изменение ответа от qntmfred.)

Вместо того, чтобы оставлять эту странную закрывающуюся открытую скобку, просто используйте обычную немедленно вызываемую функцию.

Результат будет заключаться в том, что оптимизационная структура будет обертывать это в другом наборе круглых скобок, но оставляет ваш С# намного яснее.

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>