Angular с несколькими шаблонами
Задача:
- Показать контакт.
- Контакты - данные JSON, допустим {name: "Mark", местоположение: "Англия", телефоны: [...]}.
- Контакт может отображаться несколькими способами: компактный/подробный/расширенный с дополнительной информацией (общие контакты - дополнительная директива).
Поскольку контакт может отображаться на разных страницах в разных местах, естественно создать директиву (виджет) для контакта, но вот вопрос: "Как организовать такой же виджет с несколькими шаблонами?"
Параметры:
- Создать одну директиву с одним шаблоном, который скрывает разделы
в зависимости от типа контакта - большой шаблон, возможно, много
ng-switch и ng-if
- Создать директиву для каждого шаблона - почти
те же директивы с только другим шаблоном (или templateURL)
- Для
динамически загружать шаблоны при связывании - возникают проблемы с
переключение и замена (слияние атрибутов)
Как вы решаете эту проблему?
Ответы
Ответ 1
Лично я считаю, что Вариант 2 предлагает чистое разделение между режимами отображения. Я создал рабочий пример CodePen, чтобы проиллюстрировать, как это можно сделать с помощью отдельных директив для каждого шаблона.
Метод, который я использовал в моем примере CodePen, использует шаблон factory, который вводится в каждую директиву через Angular DI. Реализация шаблона factory очень чиста, так как она просто использует ng-include строки шаблонов для каждого из поддерживаемых режимов отображения (компактный и подробный). Фактические HTML-шаблоны (частичные) могут размещаться во внешних файлах просмотра или внутренних script -блоках.
Использование контактных директив легко:
<contact compact ng-repeat="contact in contacts" ng-model="contact"></contact>
Это создает компактную версию списка контактов.
<contact detailed ng-repeat="contact in contacts" ng-model="contact"></contact>
Это создает подробный список контактов.
Я признаю, что я не использовал такой код для производства, поэтому может быть масштабируемость или другие проблемы, которые я не рассматривал. Надеюсь, код, который я предоставил, отвечает на ваши вопросы или, по крайней мере, дает вдохновение для дальнейшего изучения.
Ответ 2
У меня есть новый подход, работающий над примером Адама и использующий также образец из angular docs, в котором они говорят о функциях в свойстве templateUrl https://docs.angularjs.org/guide/directive, это плункер из angular docs: http://plnkr.co/edit/h2CSf2WqCLYfPvzL9WQn?p=preview
.directive('myCustomer', function() {
return {
templateUrl: function(elem, attr){
return 'customer-'+attr.type+'.html';
}
};
});
И это мое ремикшированное решение:
http://codepen.io/anon/pen/wawOyz?editors=101
app.factory('templates', function() {
return {
compact: 'compact',
detailed: 'detailed'
};
});
app.directive('contact', function(templates) {
return {
restrict: 'E',
templateUrl: function($elem, $attr){
return templates[$attr.mode];
},
scope: {
contact: '=ngModel'
}
};
});
Мне понравилась идея иметь все адреса шаблонов в одном factory, но я нахожу, что директива-для-режима вполне повторяется, и если у вас есть несколько элементов, использующих этот подход, вам нужно будет импоставить их (контакт-текст, текст, фирменный текст), чтобы они не разбивались.
Я еще не уверен, что это лучший способ пойти, короче и более СУХОЙ, но, возможно, сложнее тестировать или менее настраивать. Я просто хотел использовать этот подход, если он может помочь кому-либо.