Есть ли способ предварительной загрузки шаблонов при использовании маршрутизации AngularJS?

После загрузки приложения Angular мне нужно, чтобы некоторые шаблоны были доступны в автономном режиме.

Что-то вроде этого было бы идеально:

$routeProvider
  .when('/p1', {
    controller: controller1,
    templateUrl: 'Template1.html',
    preload: true
  })

person andersh    schedule 10.09.2013    source источник
comment
Sobieck00 дает здесь лучший ответ, который соответствует исходному вопросу stackoverflow.com/a/23522925/956658   -  person Dreamwalker    schedule 20.06.2014


Ответы (5)


Существует служба кэширования шаблонов: $templateCache, которую можно использовать для предварительной загрузки шаблонов. в модуле javascript.

Например, взято из документации:

var myApp = angular.module('myApp', []);
  myApp.run(function($templateCache) {
  $templateCache.put('templateId.html', 'This is the content of the template');
});

Существует даже грубая задача для предварительного создания модуля javascript из файлов html: grunt-angular-templates

Другой способ, возможно, менее гибкий, заключается в использовании встроенных шаблонов, например, с помощью тега скрипта, подобного этому, в файле index.html:

<script type="text/ng-template" id="templates/Template1.html">template content</script>

означает, что к шаблону можно обращаться позже так же, как к реальному URL-адресу в конфигурации маршрута (templateUrl: 'templates/Template1.html')

person garst    schedule 10.09.2013
comment
Спасибо, как раз то, что я искал! Мне бы очень хотелось иметь возможность указать файл шаблона в $templateCache.put(), альтернатива тегу скрипта портит мою IDE, и я не использую grunt. В итоге я использовал $http. Смотрите мой собственный ответ для деталей. - person andersh; 10.09.2013
comment
Я еще не тестировал этот плагин Grunt, но... включает ли он контроллеры? Или только шаблоны? Было бы неплохо предварительно загрузить все, что возможно, для быстрой загрузки просмотров. Спасибо! - person derrylwc; 07.05.2014
comment
+1 для встроенных шаблонов. Встроенные шаблоны обеспечивают более быструю начальную загрузку, но с возможностью замены содержимого позже. - person elkelk; 07.08.2014
comment
@derrylwc: В данный момент я борюсь с противоположной проблемой. У меня есть проект, созданный с помощью генератора grunt (grunt-angular-fullstack), который автоматически включает и настраивает множество задач grunt. Один из них — grunt-angular-templates. Так как я хочу перехватить загрузку с сервера с помощью своего фреймворка аутентификации, мне нужны запросы к серверу, но я их не получаю. Так что да, он также загружает файлы controller.js. - person andreas; 05.09.2014
comment
Если ваш шаблон необходимо получить с URL-адреса: myApp.run(function($templateRequest) { $templateRequest('/url/to/template.html', true); }); - person Blaise; 17.03.2015

Это дополнение к ответу @gargc.

Если вы не хотите использовать тег script для указания своего шаблона и хотите загружать шаблоны из файлов, вы можете сделать что-то вроде этого:

    myApp.run(function ($templateCache, $http) {
        $http.get('Template1.html', { cache: $templateCache });
    });

    myApp.config(function ($locationProvider, $routeProvider) {
        $routeProvider.when('/p1', { templateUrl: 'Template1.html' })
    });
person andersh    schedule 10.09.2013
comment
кстати, $http.get('Template1.html', {cache: $templateCache}); должен иметь такой же эффект. Хотя особой разницы нет :) - person garst; 10.09.2013
comment
Это определенно более простая альтернатива, чем то, что я предложил. Спасибо еще раз :) - person andersh; 11.09.2013
comment
Я предпочитаю это решение, поскольку оно не требует создания файла JavaScript из шаблонов HTML. - person Daniel Buckmaster; 17.12.2013
comment
эта строка $http.get('Template1.html', {кеш: $templateCache}); также означает, что вы добавляете его в угловой кеш? - person GomuGomuNoRocket; 19.12.2016
comment
Я пробовал это, но поскольку http.get является асинхронным, мой шаблон еще не был загружен в тот момент, когда он мне действительно нужен. Кто-нибудь знает, как обойти это? - person Stif; 11.01.2017
comment
не работает для меня. Я даже запускал его в консоли, и ничего не произошло. - person Saeed Neamati; 27.01.2017

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

$routeProvider.when('/p1', { controller: controller1, templateUrl: 'Template1.html', preload: true })

Это позволяет вам просто украсить свой маршрут и не беспокоиться об обновлении другой конфигурации предварительной загрузки где-то еще.

Вот код, который запускается при запуске:

angular.module('MyApp', []).run([
    '$route', '$templateCache', '$http', (function ($route, $templateCache, $http) {
        var url;
        for (var i in $route.routes) {
            if ($route.routes[i].preload) {
                if (url = $route.routes[i].templateUrl) {
                    $http.get(url, { cache: $templateCache });
                }
            }
        }
    })
]);
person Thomas Sobieck    schedule 07.05.2014
comment
Я бы немного изменил его, чтобы не выполнять предварительную загрузку, если есть явное preload: false, поэтому предварительная загрузка включена для маршрута по умолчанию. Но я думаю, что решение это личный вкус и зависит от того, что вы хотите сделать. Помимо этого отличного фрагмента! +1 - person Anticom; 01.07.2014
comment
Когда я написал, что просто хотел загрузить два маршрута примерно из 20 или около того. Итак, явное preload: true сработало для меня немного лучше. - person Thomas Sobieck; 01.07.2014
comment
Это, безусловно, лучший ответ. - person Fernando Silveira; 04.03.2015
comment
Я очень рад найти ваш ответ здесь.. Я изо всех сил пытался найти способ кэшировать мои шаблоны.. спасибо - person user1455719; 14.06.2015
comment
Может кто-нибудь объяснить, если (url = $route.routes[i].templateUrl), это задание - когда это вернет false? - person CountZero; 03.01.2016
comment
@CountZero JavaScript приравняет пустую строку к false. Если какая-либо строка вообще задана, независимо от того, какое у нее значение (может быть даже 0 или false), она будет равна true - person Ahatius; 18.03.2016
comment
Если, как и я, вы искали решение с использованием uiRouter и вам понравилась эта идея: попробуйте это. Он загрузит шаблон для состояния и любых представлений, которые он определил. - person Knyri; 04.05.2017
comment
как можно предварительно загрузить шаблоны, определенные в компоненте, а не в состоянии маршрутизатора? - person indusBull; 27.10.2017

Предварительно загружает все шаблоны, определенные в маршрутах модуля.

angular.module('MyApp', [])
.run(function ($templateCache, $route, $http) {
    var url;
    for(var i in $route.routes)
    {
      if (url = $route.routes[i].templateUrl)
      {
        $http.get(url, {cache: $templateCache});
      }
    }
})
person Raman Savitski    schedule 06.02.2014
comment
Что произойдет, если содержимое шаблона будет динамически изменяться? Это отображается правильно или будет отображаться тот же контент, что и из кеша? - person Mr. D MX; 25.10.2016
comment
Если контент динамический - нет смысла его предварительно загружать. Или я не понимаю вашего случая. - person Raman Savitski; 24.03.2017

если вы завернете каждый шаблон в тег скрипта, например:

<script id="about.html" type="text/ng-template">
<div>
    <h3>About</h3>
    This is the About page
    Its cool!
</div>
</script>

Объедините все шаблоны в один большой файл. Если вы используете Visual Studio 2013, загрузите Web Essentials — он добавляет контекстное меню для создания HTML-пакета.

Добавьте код, который этот парень написал, чтобы изменить угловой сервис $templatecache - это всего лишь небольшой фрагмент кода, и он работает :-)

https://gist.github.com/vojtajina/3354046

ШаблонUrl ваших маршрутов должен выглядеть следующим образом:

        $routeProvider.when(
            "/about", {
                controller: "",
                templateUrl: "about.html"
            }
        );
person Simon Dowdeswell    schedule 03.02.2014