Динамический URL-адрес шаблона — AngularJS

Итак, начиная с Angular 1.1.4, у вас может быть динамический URL-адрес шаблона. Из здесь,

templateUrl — то же, что и template, но шаблон загружается с указанного URL-адреса. Поскольку загрузка шаблона является асинхронной, компиляция/связывание приостанавливается до загрузки шаблона.

Вы можете указать templateUrl как строку, представляющую URL-адрес, или как функцию, которая принимает два аргумента tElement и tAttrs (описанные в API функции компиляции ниже) и возвращает строковое значение, представляющее URL-адрес.

Как я могу использовать это для создания динамического шаблона на основе, скажем, атрибута моей директивы? Очевидно, это не работает, так как tAttrs.templateType — это просто строка templateType.

templateUrl: function (tElement, tAttrs) {
  if (tAttrs.templateType == 'search') {
    return '/b/js/vendor/angular-ui/template/typeahead/typeahead.html'
  } else {
    return '/b/js/vendor/angular-ui/template/typeahead/typeahead2.html'
  }
}

Учитывая, что у меня нет доступа к области, как мне с этим справиться?


person Scott Silvi    schedule 12.06.2013    source источник
comment
Начиная с Angular 1.2.17 (и, возможно, ранее) ваша первоначальная идея, кажется, работает.   -  person Maximilian Hils    schedule 12.06.2014


Ответы (4)


Для создания динамических шаблонов в AngularJS также возможно следующее: В вашей директиве используйте:

template : '<div ng-include="getTemplateUrl()"></div>'

Теперь ваш контроллер может решить, какой шаблон использовать:

$scope.getTemplateUrl = function() {
  return '/template/angular/search';
};

Поскольку у вас есть доступ к параметрам вашей области видимости, вы также можете сделать следующее:

$scope.getTemplateUrl = function() {
  return '/template/angular/search/' + $scope.query;
};

Таким образом, ваш сервер может создать для вас динамический шаблон.

person Ruud    schedule 15.08.2013
comment
Хотя это интересно, однако, кажется, что это идет вразрез с дизайном angular, потому что вводит зависимость между директивой и контроллером, которая ослабляет инкапсуляцию и автономные возможности директивы. - person Jarnal; 10.10.2013
comment
Вместо этого вы можете объявить/назначить динамическую функцию внутри свойства link: в директиве, поскольку ссылка может принимать обратный вызов function(scope, element, attrs), который обеспечивает доступ к scope. Это улучшает его способность стоять в одиночестве. - person cjn; 14.08.2015

Итак, проблема заключалась в том, как я взломал директиву typeahead... Я устанавливал переменную области видимости в typeahead, которая будет оцениваться в директиве typeaheadPopup. Вместо этого я просто передал атрибут templateType напрямую как строку и оценил ее. Например.

var popUpEl = angular.element(
  "<typeahead-popup " +
    "matches='matches' " +
    "active='activeIdx' " +
    "select='select(activeIdx)' " +
    "template-type='" + attrs.templateType + "'" +
    "query='query' " +
    "position='position'>" +
  "</typeahead-popup>");

Вместо "template-type='templateType'"

person Scott Silvi    schedule 13.06.2013

Столкнулся с аналогичной проблемой при создании резервной копии загрузки файлов для браузеров, не поддерживающих File API (‹ IE10). Ключевое отличие в том, что мне нужна была страница, чтобы разумно решить, какой шаблон отображать, без использования значения атрибута для включения.

В итоге я использовал поставщика constant для своей директивы. Константы в основном устанавливают параметры по умолчанию, которые могут быть введены в любом месте вашей директивы. Я просто позволяю константе вызывать функцию для определения поддержки браузера, а затем ссылаюсь на это значение, когда мне нужно определить, какой шаблон вытащить. Это удобно, поскольку 1) нет атрибута для ссылки и 2) он доступен на этапе предварительной ссылки, когда у вас нет доступа к контроллеру.

(function () {
  var myDir = angular.module('myDir', []);
  myDir.constant('myDirConfig', {
      hasFileSupport: fileApiIsSupported()
    });

  myDir.directive('myDir', ['myDirConfig', function (myDirConfig) {
      return {
          templateUrl: function () {
              if (myDirConfig.hasFileSupport) {
                  return 'pathToTemplate/html5.html';
              } else {
                  return 'pathToTemplate/fallback.html';
              }
          }
      };
  }];

  function fileApiIsSupported() { return (...); }
})();
person iamsar    schedule 31.07.2015

person    schedule
comment
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и/или как этот код отвечает на вопрос, повышает его ценность в долгосрочной перспективе. - person ryanyuyu; 08.09.2015