Можете ли вы переопределить определенные шаблоны в AngularUI Bootstrap?

Мне любопытно, есть ли способ переопределить отдельные конкретные шаблоны из файла ui-bootstrap-tpls. Подавляющее большинство шаблонов по умолчанию соответствуют моим потребностям, но есть пара конкретных, которые я хотел бы заменить, не проходя весь процесс захвата всех шаблонов по умолчанию и их подключения к версии без tpls.


person Jeremy Privett    schedule 15.07.2013    source источник
comment
Я также обнаружил, что украшаю службу $modal, чтобы получить больше возможностей для настройки, не создавая (надеюсь) слишком много головной боли при обслуживании. $provide.decorator('$modal'... В моем случае я не хотел отображать элемент modalWindow. Всегда. Я просто не использовал его, и это было лучшее, что я мог придумать. Я хотел бы услышать лучший способ, если у кого-то есть.   -  person bodine    schedule 03.09.2014


Ответы (4)


Да, директивы из http://angular-ui.github.io/bootstrap легко настраиваются, и их легко переопределить. один из шаблонов (и по-прежнему полагаться на шаблоны по умолчанию для других директив).

Достаточно передать $templateCache, либо напрямую (как это делается в файле ui-bootstrap-tpls), либо, что проще, переопределить шаблон с помощью директивы <script> (документ).

Надуманный пример, в котором я меняю шаблон оповещения, чтобы поменять местами x на Close, показан ниже:

<!doctype html>
<html ng-app="plunker">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.4.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">

    <script id="template/alert/alert.html" type="text/ng-template">
      <div class='alert' ng-class='type && "alert-" + type'>
          <button ng-show='closeable' type='button' class='close' ng-click='close()'>Close</button>
          <div ng-transclude></div>
      </div>
    </script>
  </head>

  <body>
    <div ng-controller="AlertDemoCtrl">
      <alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">                     
        {{alert.msg}}
      </alert>
      <button class='btn' ng-click="addAlert()">Add Alert</button>
    </div>
  </body>
</html>

Плункер в реальном времени: http://plnkr.co/edit/gyjVMBxa3fToYTFJtnij?p=preview

person pkozlowski.opensource    schedule 16.07.2013
comment
Мне нравится этот ответ. Мне просто не нравится тот факт, что он не включен на страницу документации Angular UI, и мне потребовалось довольно много времени, чтобы понять, как сделать что-то столь же простое, как отображение модального окна. - person trivektor; 28.09.2013
comment
Документация @BruceBanner и надежные рабочие примеры — два самых больших недостатка пользовательского интерфейса Angular. Проект отличный, но ему нужна сладкая нежная любовь разработчиков. - person Robin van Baalen; 25.09.2014
comment
@RobinvanBaalen это функция angular-js (не angular-ui), это уже задокументировано в официальных документах angular js - person vikki; 27.09.2014
comment
Пожалуйста, проверьте ответ @JcT о $provide.decorator, так как это способ Angular (хороший способ в данном случае) для переопределения шаблонов директив. И это довольно легко. Простое добавление/переопределение шаблона в $templateCache на самом деле не лучшая практика. - person John Bernardsson; 01.07.2015
comment
@Джон, я не уверен, откуда вы берете вещи, которые подходят для Angular (хороший способ в данном случае), и простое добавление/переопределение шаблона в $templateCache на самом деле не лучшая практика, а как один из сопровождающих angular-ui и angular Я могу заверить вас, что нет ничего плохого в переопределении шаблонов. Если у вас нет конкретных вопросов, чтобы поделиться... - person pkozlowski.opensource; 01.07.2015
comment
Ну, проблема не в переопределении шаблонов. Речь идет о шаблоне, используемом для этого. В шаблоне Decorator, на который я указываю (используется в другом ответе), для этого конкретного случая речь идет только о переопределении шаблона. Разница заключается в шаблоне, который позволяет указать четко определенную точку для изменения (украшения) Директивы, в отличие от шаблона, который определяет шаблон как бы в глуши, чей идентификатор является идентификатором шаблона из какого-то директиву, которую вы хотите изменить. Первый очень четко понимает, что делает, а второй, я думаю, нет. - person John Bernardsson; 02.07.2015
comment
Следовательно, простое добавление/переопределение шаблона в $templateCache на самом деле не является лучшей практикой :) Может быть, мне следует изменить его на: простое добавление/переопределение шаблона в $templateCache для изменения директивы на самом деле не является лучшей практикой. Кроме того, я рассматриваю Angular $templateCache именно как кеш, поэтому браузеру не нужно запрашивать его каждый раз, когда рисуется, а не как карту, для которой вы создаете переопределяющие шаблоны шаблонов. Вот тут-то и появляется фраза о том, что это Angular (хороший способ в данном случае). Но я согласен, что это всего лишь мнение, конечно :) - person John Bernardsson; 02.07.2015

Использование $provide.decorator

Использование $provide для оформления директивы избавляет от необходимости напрямую возиться с $templateCache.

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

angular.module('plunker', ['ui.bootstrap'])
  .config(['$provide', Decorate]);

  function Decorate($provide) {
    $provide.decorator('alertDirective', function($delegate) {
      var directive = $delegate[0];

      directive.templateUrl = "alertOverride.tpl.html";

      return $delegate;
    });
  }

Форк plunkr pkozlowski.opensource: http://plnkr.co/edit/RE9AvUwEmKmAzem9mfpI?p=preview

(Обратите внимание, что вы должны добавить суффикс «Директива» к имени директивы, которую вы собираетесь декорировать. Выше мы украшаем директиву alert UI Bootstrap, поэтому мы используем имя alertDirective.)

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

person JcT    schedule 13.10.2014
comment
Это правильное решение, и оно следует лучшим практикам angular. Вы НИКОГДА не должны использовать строки для создания HTML, и вам не нужно явно включать их в файл index.html, куда вы вставляете сторонние скрипты. Спасибо @JcT! - person TommyMac; 16.04.2015
comment
Здравствуйте, alertDirective это ключевое слово? если да, то какое ключевое слово для Tabs? Я пытаюсь сделать то же самое на вкладках, но я просмотрел alert.js и не вижу, где у них там было alertDirective. - person codenamezero; 28.05.2015
comment
angularjs $compileProvider прикрепляет суффикс «Директива» к имени вашей директивы при ее регистрации (аналогично $filterProvider с суффиксом «Фильтр»); для большинства целей это невидимо, но при украшении вам нужно будет добавить этот суффикс к директиве, на которую вы собираетесь ориентироваться. Например, tabDirective или tabsetDirective и т. д. Не совсем четко задокументировано нигде, что я мог найти, но вот ссылка на аналогичное поведение по крайней мере для $filterProvider: docs.angularjs.org/api/ng/provider/$filterProvider - person JcT; 28.05.2015
comment
Большое спасибо @JcT, отличный ответ. Это правильный путь. И, как вы говорите, хорошая отправная точка для украшения сторонних директив :) - person John Bernardsson; 01.07.2015
comment
Решение сработало и для меня. Есть ли способ использовать шаблон по умолчанию и пользовательский шаблон для одной и той же директивы Bootstrap в разных модулях? Кажется, что мой пользовательский шаблон всегда переопределяет стандартный. - person Valera Tumash; 10.02.2016
comment
это решение не работает с angular-ui 1.3.2. см. планк plnkr.co/edit/E88IsLodO2a7CvH6gcC6?p=preview - person ps0604; 06.05.2016
comment
В этом планке были некоторые другие несвязанные ошибки; например, 1.3.2 использует директивы с префиксом, такие как «uib-alert» вместо «alert» (обратите внимание, что он также включает поддержку «template-url» для переопределения шаблонов). Исправлено: plnkr.co/edit/sIIaTX?p=preview - person JcT; 09.05.2016
comment
@ValeraTumash: Извините за поздний ответ. Да, я думаю, что ваша конфигурация будет уничтожена; однако из Angular v1.3 я считаю, что вы можете указать function(element, attributes) для templateUrl. Вы можете использовать это для некоторого динамического поведения (возврат исходной функции templateUrl или вашей собственной строки URL-адреса в зависимости от атрибута и т. д.). Тем не менее, ui.bootstrap теперь также использует ту же функциональность, чтобы вы могли указать атрибут template-url в директиве, поэтому вы также можете потенциально использовать это, если вы согласны указать путь к шаблону напрямую через атрибут элемента директивы. - person JcT; 09.05.2016
comment
красивое и элегантное решение. - person chyupa; 15.06.2016
comment
Лучшее решение, работает в большинстве случаев! Спасибо - person Lunin Roman; 07.09.2018

Ответ от pkozlowski.opensource действительно полезен и мне очень помог! Я настроил его в моем состоянии, чтобы иметь один файл, определяющий все мои переопределения шаблона angular, и загрузил внешний JS, чтобы уменьшить размер полезной нагрузки.

Для этого перейдите в конец исходного js-файла angular ui-bootstrap (например, ui-bootstrap-tpls-0.6.0.js) и найдите интересующий вас шаблон. Скопируйте весь блок, определяющий шаблон, и вставьте его в JS-файл переопределений.

e.g.

angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/alert/alert.html",
     "      <div class='alert' ng-class='type && \"alert-\" + type'>\n" +
     "          <button ng-show='closeable' type='button' class='close' ng-click='close()'>Close</button>\n" +
     "          <div ng-transclude></div>\n" +
     "      </div>");
}]);

Затем просто включите файл переопределений после ui-bootstrap, и вы получите тот же результат.

Разветвленная версия проекта pkozlowski.opensource http://plnkr.co/edit/iF5xw2YTrQ0IAalAYiAg?p=preview

person Matt Byrne    schedule 01.11.2013
comment
Я использую тот же шаблон, и хотя он работает; Я действительно хочу, чтобы был лучший способ. Я думаю, что предпочел бы конфигурацию затиранию. - person bodine; 03.09.2014

Вы можете использовать template-url="/app/.../_something.template.html", чтобы переопределить текущий шаблон для этой директивы.

(По крайней мере, работает в Accordion Bootstrap.)

person crimson    schedule 13.11.2015