В моем угловом приложении у меня есть несколько экземпляров $modal, которые создаются следующим образом:

var modalInstance = $modal.open({
        templateUrl: APP_CONFIG.TPL_PATH + '/path/template.html',
        controller: 'TemplateController'//...
});

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

Я нашел это как "решения" до сих пор:

// first one
$rootScope.$on('$stateChangeStart', function(event, next, current) {
    $templateCache.remove(current.templateUrl);
}); // doesn't work because $modal doesn't change state

// second one
$rootScope.$on('$viewContentLoaded', function() {
    $templateCache.removeAll();
}); // mess Bootstrap UI which adds default partials directly to the $templateCache

// third one
$modal.open({
            templateUrl: '/app/components/your-modal.html?bust=' + Math.random().toString(36).slice(2),
            controller: 'YourModalController'
        }); // ugly and inefficient - I have to change multiple code blocks for every modal

Есть ли достаточные решения? Заранее спасибо.

ИЗМЕНИТЬ

Дополнительный совет, который я получил, - это изменить данные шаблона и поместить их в файлы .js (т.е. <p>Data</p> в <p>{{data}}</p> и $scope.data = 'Data' в .js). Здесь я вижу две проблемы. Как я могу быть уверен, что файл .js не кэшируется браузером? Как я могу добавить дополнительные изменения в структуру шаблона (дополнительные переменные), если он кешируется (т.е. в <p>{{data}}</p><img src='{{imageUrl}}>')?

4
Georgy 18 Дек 2015 в 14:50

4 ответа

Лучший ответ

Что ж, когда мы говорим о «достаточном», это вопрос вкуса и особой проблемы, но я нашел этот ответ вполне удовлетворительным:

Вы не можете удалить кеш браузера напрямую с помощью JavaScript. Это связано с требованием безопасности. И это немного неправильно - многие умные разработчики лучше знают, что хранить и что удалять. Но есть простой прием: использование ?keyword=hash. Даже если страницы, которые вы видите, будут похожими, если для них будут разные хэши, браузер сохранит две версии страниц. Добавление ?keyword=hash в каждый $model.open() раздражает и непрофессионально (СУХОЙ, ПОЦЕЛУЙ). Давайте использовать угловой interceptors тогда.

yourApp.factory('HttpInterceptor', function($templateCache, APP_CONFIG) {
  return {
    'request': function(request) {
      if (request.method === 'GET' && $templateCache.get(request.url) === undefined) {
        request.url += '?ver=' + APP_CONFIG.VERSION;
      }
      return request;
    }
  };
});

Поместите это в $httpProvider.interceptors:

$httpProvider.interceptors.push('HttpInterceptor');

Теперь вы можете указать номер версии (например, взять его из репозитория или включить метки времени). Версия изменена - браузер загружает новую версию ваших шаблонов. Условие if $templateCache.get(request.url) === undefined используется для фильтрации запросов на предварительно кэшированный (возможно, автоматически вставленный) контент. Идея перехватчиков взята отсюда: https://stackoverflow.com/a/25060769/4753661.

4
Community 23 Май 2017 в 12:02

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

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Cache-Control" value="no-cache, no-store, must-revalidate" />
        <add name="Pragma" value="no-cache" />
        <add name="Expires" value="0" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
0
Kevin Able 2 Дек 2016 в 00:16

Краткое описание предоставленных вариантов

Первый и второй варианты.

// first one
$rootScope.$on('$stateChangeStart', function(event, next, current) {
    $templateCache.remove(current.templateUrl);
}); // doesn't work because $modal doesn't change state

// second one
$rootScope.$on('$viewContentLoaded', function() {
    $templateCache.removeAll();
}); // mess Bootstrap UI which adds default partials directly to the $templateCache

Вы, безусловно, не хотите произвольно очищать элементы от $templateCache, что похоже на то, что делали ваши первые два варианта. Тогда Angular придется снова и снова добавлять представления в templateCache.

Третий вариант:

$modal.open({
            templateUrl: '/app/components/your-modal.html?bust=' + Math.random().toString(36).slice(2),
            controller: 'YourModalController'
        }); // ugly and inefficient - I have to change multiple code blocks for every modal

Это фактически приведет к утечке памяти, потому что теперь у вас будет бесконечное количество шаблонов, добавляемых в $ templateCache.

Лучшие решения

Мой рекомендуемый ответ

Я бы рекомендовал переименовать ваш файл template.html, чтобы иметь уникальные идентифицируемые имена.

< EM> т.е . modalTemplate_alertModal.html, modalTemplate_newEmployeeModal.html ...

Тогда вы действительно сможете использовать преимущества $templateCache и повысить производительность.

Если вы абсолютно не можете переименовать файлы template.html.

В этом случае вы можете удалить конкретный шаблон из templateCache, прежде чем открывать модальный.

//Get TemplateURL
var TemplateURL = APP_CONFIG.TPL_PATH + '/path/template.html';

//Remove Cached ModalTemplate
$templateCache.remove(TemplateURL);

//Open Modal
var modalInstance = $modal.open({
        templateUrl: TemplateURL,
        controller: 'TemplateController'//...
});
1
Malkus 18 Дек 2015 в 12:14

У меня может быть статический заголовок (т.е. <h2>Create new entry</h2>). А затем изменить его (_ <h2>Create new user entry</h2>). Если бы я ранее просматривал модал, я бы не получил обновленный заголовок без очистки кеша.

Основываясь на этом утверждении, вы действительно хотите использовать controller и $scope для обновления этих значений.

<h2>{{modalHeader}}</h2>

Затем, где бы вы ни определяли, какой заголовок должен быть обновлен, его значение

$scope.modalHeader = "Create new user entry";

Помните, что angularjs компилирует и управляет DOM, единственный способ правильно изменить значения DOM - использовать directives.

0
Malkus 18 Дек 2015 в 14:04