Подтвердить что ты не робот

Angular с несколькими шаблонами

Задача:

  • Показать контакт.
  • Контакты - данные JSON, допустим {name: "Mark", местоположение: "Англия", телефоны: [...]}.
  • Контакт может отображаться несколькими способами: компактный/подробный/расширенный с дополнительной информацией (общие контакты - дополнительная директива).

Поскольку контакт может отображаться на разных страницах в разных местах, естественно создать директиву (виджет) для контакта, но вот вопрос: "Как организовать такой же виджет с несколькими шаблонами?"

Параметры:

  • Создать одну директиву с одним шаблоном, который скрывает разделы в зависимости от типа контакта - большой шаблон, возможно, много ng-switch и ng-if
  • Создать директиву для каждого шаблона - почти те же директивы с только другим шаблоном (или templateURL)
  • Для динамически загружать шаблоны при связывании - возникают проблемы с переключение и замена (слияние атрибутов)

Как вы решаете эту проблему?

4b9b3361

Ответ 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, но я нахожу, что директива-для-режима вполне повторяется, и если у вас есть несколько элементов, использующих этот подход, вам нужно будет импоставить их (контакт-текст, текст, фирменный текст), чтобы они не разбивались.

Я еще не уверен, что это лучший способ пойти, короче и более СУХОЙ, но, возможно, сложнее тестировать или менее настраивать. Я просто хотел использовать этот подход, если он может помочь кому-либо.