Чи можете ви замінити певні шаблони в AngularUI Bootstrap?


88

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


1
Я також виявив, що прикрашаю $modalпослугу, щоб отримати більше можливостей налаштування, не створюючи (сподіваюся) занадто сильного головного болю в обслуговуванні. $provide.decorator('$modal'... У моєму випадку я не хотів відображати modalWindowелемент. Ніколи. Я просто не використовував його, і це було найкраще, що я міг придумати. Я хотів би почути кращий спосіб, якщо хтось його має.
bodine

Відповіді:


123

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

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

Надуманий приклад , коли я міняю шаблон ALERT, щоб своп 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


19
Мені подобається така відповідь. Мені просто не подобається той факт, що він не включений на сторінку документації Angular UI, і мені знадобився досить довгий час, щоб зрозуміти, як зробити щось таке просте, як показ модального.
Tri Vuong

2
Документація @BruceBanner та надійні приклади роботи - два найбільших падіння Angular UI. Проект чудовий, але йому потрібна солодка ніжна любов розробника.
Робін ван Бален

1
@RobinvanBaalen це функція angular-js (не angular-ui), вона вже задокументована в офіційних документах
angular

Будь ласка, перевірте відповідь @JcT щодо $ provide.decorator, оскільки це кутовий спосіб (хороший спосіб у цьому випадку) замінити шаблони директив. І це досить просто. Просто додавання / перевизначення шаблону до $ templateCache насправді не є найкращою практикою.
Джон Бернардссон,

@John Я не впевнений, звідки ти береш речі "це кутовий спосіб (у цьому випадку хороший спосіб)" і "просто додавання / перевизначення шаблону до $ templateCache насправді не найкраща практика", але як один з angular- користувальницький інтерфейс та кутові супровідники Я можу запевнити вас, що нічого поганого в перевизначенні шаблонів немає. Якщо у вас немає конкретних питань, якими можна поділитися ...
pkozlowski.opensource

79

Використовуючи $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;
    });
  }

Форк додаткового модуля pkozlowski.opensource: http://plnkr.co/edit/RE9AvUwEmKmAzem9mfpI?p=preview

(Зверніть увагу, що ви повинні додати суфікс „Директива“ до назви директиви, яку ви збираєтеся прикрасити. Вище ми прикрашаємо alertдирективу Bootstrap інтерфейсу користувача , тому ми використовуємо це ім’я alertDirective.)

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


9
Це правильне рішення, яке відповідає найкращим практикам. Вам НІКОЛИ не слід використовувати рядки для створення HTML, а також не потрібно чітко включати його у файл index.html, куди ви вводите сторонні сценарії. Дякую @JcT!
TommyMac

2
Привіт, це alertDirectiveключове слово? якщо так, для чого потрібне ключове слово Tabs? Я намагаюся зробити подібне на вкладках, але я переглянув alert.js і не бачу, де вони alertDirectiveтам були.
codenamezero

4
Angularjs $compileProviderдодає суфікс "Директива" до імені вашої директиви, коли ви її реєструєте ( $filterProviderаналогічно це робить із суфіксом "Фільтр"); для більшості цілей це невидимо, але під час оформлення вам потрібно буде додати цей суфікс до директиви, на яку ви збираєтесь націлитись. Наприклад, tabDirectiveабо tabsetDirectiveтощо. Ніде точно не задокументовано, де б я не міг знайти, але ось посилання на подібну поведінку $filterProviderпринаймні: docs.angularjs.org/api/ng/provider/$filterProvider
JcT,

2
Велике спасибі @JcT, чудова відповідь. Це правильний шлях. І, як ви кажете, хороша відправна точка для "оздоблення" директив третьої сторони :)
Джон Бернардссон,

1
@ValeraTumash: Вибачте за пізню відповідь. Так, я думаю, що ваша конфігурація буде заблокована; однак, з Angular v1.3, я вважаю, ви можете надати a function(element, attributes)до templateUrl. Ви можете використовувати це для певної динамічної поведінки (повернути оригінальну функцію templateUrl або власний рядок URL-адреси залежно від атрибута тощо). Однак, ui.bootstrap тепер також використовує цю саму функціональність, щоб дозволити вам вказувати template-urlатрибут директиви, тому ви також можете потенційно використовувати це, якщо будете раді надавати шлях до шаблону безпосередньо через атрибут елемента директиви.
JcT

27

Відповідь від pkozlowski.opensource дійсно корисна і мені дуже допомогла! Я змінив його в моєму стані, щоб мати один файл, що визначає всі мої кутові перевизначення шаблону, і завантажив зовнішній JS, щоб зменшити розмір корисного навантаження.

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

напр

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 «s бухнутися http://plnkr.co/edit/iF5xw2YTrQ0IAalAYiAg?p=preview


1
Я використовую цей самий шаблон, і хоча він працює; Я б дуже хотів, щоб був кращий спосіб. Думаю, я віддав би перевагу конфігурації, аніж клоубонгу.
bodine

7

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

(Працює принаймні в Bootstrap з акордеону.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.