2015-08-04 6 views
5

Я создаю директивы для библиотеки, которую могут использовать клиенты. Мне нужно, чтобы клиенты создали свои собственные шаблоны для директивы и передали абсолютное значение URL этого шаблона в мои директивы. Одна из моих директив будет содержать в себе другую настраиваемую директиву, и шаблон будет вычислен на основе значения одного из атрибутов родительской директивы. Вот пример:Передача атрибута родительской директивы атрибуту дочерней директивы

<parent-dir menu-template="this.html" item-template="that.html"></parent-dir> 

У меня есть шаблон для этой директивы, которая выглядит следующим образом:

<ul style="list: none" ng-repeat="item in menu"> 
    <child-dir template="{{itemTemplate}}"></child-dir> 
</ul> 

Мои директивы выглядеть следующим образом:

angular.module('myApp') 
.directive('parentDir', function() {   
    return { 
     restrict: 'E', 
     scope: { 
      menuTemplate: '@', 
      itemTemplate: '@', 
      menuType: '@', 
      menuName: '@', 
      menuId: '@', 
     }, 
     templateUrl: function (element, attrs) { 
      alert('Scope: ' + attrs.menuTemplate); 
      return attrs.menuTemplate; 
     }, 
     controller: function ($scope, $element, $attrs) { 
      $scope.defaultSubmit = false; 
      alert('Menu: '+$attrs.menuTemplate); 
      alert('Item: ' + $attrs.itemTemplate); 
      $scope.itemTemplate = $attrs.itemTemplate; 
      if ($attrs.$attr.hasOwnProperty('defaultSubmit')) { 
       alert('It does'); 
       $scope.defaultSubmit = true; 
      }    
     } 
    }; 
}) 
.directive('childDir', function() { 
    return { 
     restrict: 'E', 
     require: '^parentDir', 
     templateUrl: function (element, attrs) { 
      alert('Item Template: ' + attrs.template); 
      return attrs.template; 
     }, 
     controller: function ($scope, $element, $attrs) {     
      $scope.job; 
      alert('Under job: ' + $scope.itemTemplate); 
     } 
    }; 
}); 

Я не показывать все код, но это основная часть моей проблемы. Когда я запускаю это, я продолжаю получать неопределенный шаблон для childDir.

Какова наилучшая практика увековечивания значения itemTemplate из parentDir, чтобы childDir мог использовать его в качестве шаблона?

ответ

4

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

Другими словами: в точке, где работает функция templateUrl, значение атрибута template по-прежнему "{{itemTemplate}}". Это останется так, пока ссылка на директиву (preLink, если быть точным) работает.

Я создал плункер, чтобы продемонстрировать точку here. Не забудьте открыть консоль. Вы увидите, что templateUrl запускается перед как родительскими, так и дочерними связями.

Так что вы делаете вместо этого?

К счастью, угловой предоставляет $templateRequest услугу, которая позволяет запросить шаблон таким же образом, что бы использовать templateUrl (он также использует $templateCache что удобно).

поместить этот код в функции связи:

$templateRequest(attrs.template) 
    .then(function (tplString){ 
     // compile the template then link the result with the scope. 
     contents = $compile(tplString)(scope); 
     // Insert the compiled, linked element into the DOM 
     elem.append(contents); 
    }) 

Вы можете удалить любую ссылку на template в объекте определения директивы, и это будет безопасно работать, как только атрибуты интерполированы.

+1

Спасибо за помощь! Я пробовал это так и работает! Кроме того, я попытался использовать шаблон вместо этого и передал функцию, которая добавила бы атрибут в дочернюю директиву, установив шаблон в строку и добавив к нему attrs.itemTemplate. –

+1

Немного другой случай использования, но такая же основная проблема. Этот ответ сработал. @ Майкл, если вы рядом, вы думаете, что стоит принять этот ответ, чтобы помочь другим людям, таким как я, указав, что это хороший ответ? – sifriday

Смежные вопросы