2015-08-04 17 views
5

Tworzę dyrektywy dotyczące biblioteki, z której mogą korzystać klienci. Muszę pozwolić klientom tworzyć własne szablony dla dyrektywy i przekazywać bezwzględną wartość URL tego szablonu do moich dyrektyw. Jedna z moich dyrektyw będzie zawierała w sobie inną dyrektywę, a jej szablon zostanie opracowany na podstawie wartości jednego z atrybutów dyrektywy nadrzędnej. Oto przykład:Przekazywanie atrybutu dyrektywy nadrzędnej do atrybutu dyrektywy podrzędnej

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

Mam szablon dla tej dyrektywy, który wygląda tak:

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

moich dyrektyw wyglądać następująco:

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); 
     } 
    }; 
}); 

Ja nie pokazano wszystkich kod, ale to jest główny element mojego problemu. Gdy uruchomię to, ciągle jestem niezdefiniowany dla szablonu na childDir.

Jaka jest najlepsza praktyka w utrwalaniu wartości itemTemplate z parentDir, aby childDir mógł używać jej jako szablonu?

Odpowiedz

4

Przyczyną napotkania problemów jest to, że funkcja generująca templateUrl jest uruchamiana, zanim do dyrektywy zostanie przypisana scope - coś, co należy zrobić, zanim można będzie wstawić interpolowane dane.

Innymi słowy: w momencie uruchomienia funkcji templateUrl wartość atrybutu template to nadal "{{itemTemplate}}". Tak się stanie, dopóki nie zostanie uruchomiona funkcja linku do dyrektywy (preLink).

Stworzyłem plunkera, aby zademonstrować punkt here. Pamiętaj, aby otworzyć konsolę. Zobaczysz, że templateUrl jest uruchamiany przed funkcjami łączenia nadrzędnego i podrzędnego.

Co więc robisz zamiast tego?

Na szczęście, kątowa zapewnia usługę $templateRequest, która pozwala zażądać szablonu w taki sam sposób, jak przy użyciu templateUrl (korzysta również z użytego $templateCache).

umieścić ten kod w funkcji Link:

$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); 
    }) 

można następnie usunąć wszelkie odniesienia do template w obiekcie definicji dyrektywy, a to bezpiecznie uruchomić raz atrybut został interpolowana.

+1

Dzięki za pomoc! Próbowałem tego w ten sposób i działa! Próbowałem też użyć szablonu i przekazałem funkcję, która dodawałaby atrybut do dyrektywy child, ustawiając szablon na łańcuch i dodając do niego attrs.itemTemplate. –

+1

Nieco inny przypadek użycia, ale ten sam podstawowy problem. Ta odpowiedź zadziałała. @Michael, jeśli jesteś w pobliżu, czy uważasz, że warto zaakceptować tę odpowiedź, aby pomóc innym ludziom, takim jak ja, wskazując, że jest to dobra odpowiedź? – sifriday

Powiązane problemy