2013-06-12 15 views
14

Tak jak w Angular 1.1.4, możesz mieć dynamiczny adres URL szablonu. Od here,Dynamic templateUrl - AngularJS

templateUrl - Taki sam jak szablon, ale szablon jest ładowany z podanego adresu URL. Ponieważ ładowanie szablonu jest asynchroniczne, kompilacja/łączenie jest zawieszane do momentu załadowania szablonu.

Można określić templateUrl jako ciąg reprezentujący adres URL lub jako funkcję, która pobiera dwa argumenty tElement i tAttrs (opisane w api api funkcji poniżej) i zwraca wartość ciągu reprezentującego adres URL.

Jak mogę wykorzystać to do wygenerowania dynamicznego szablonu na podstawie, powiedzmy, atrybutu na mojej dyrektywie? Oczywiście to nie zadziała, ponieważ tAttrs.templateType jest po prostu ciąg „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' 
    } 
} 

Biorąc pod uwagę, że nie mam dostępu do zakresu, w jaki sposób poradzić sobie z tym?

+0

Jak kątowego 1.2.17 (a może wcześniej), oryginalny pomysł wydaje się działać. –

Odpowiedz

26

Poniżej jest również możliwe do tworzenia dynamicznych szablonów w angularjs: W swoim dyrektywy użytku:

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

Teraz kontroler może zdecydować, który szablon do użycia:

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

Ponieważ masz wg Jeśli chodzi o parametry zasięgu, można również:

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

Dzięki temu serwer może utworzyć dynamiczny szablon.

+14

Choć jest to interesujące, wydaje się, że jest ono sprzeczne z ziarnistością, ponieważ wprowadza zależność między dyrektywą a kontrolerem, co osłabia enkapsulację i autonomiczną zdolność dyrektywy. – Jarnal

+1

Można zamiast tego zadeklarować/przypisać funkcję dynamiczną wewnątrz właściwości 'link:' w dyrektywie, ponieważ link może przyjąć funkcję 'callback (scope, element, attrs)', która zapewnia dostęp do 'scope'. To poprawia jego zdolność do samodzielnego działania. – cjn

1

Problem polegał na tym, jak zhakowałem dyrektywę typu ... Ustawiałem zmienną zasięgu na nagłówku, który ma być oceniany w dyrektywie typeaheadPopup. Zamiast tego właśnie przekazałem atrybut templateType bezpośrednio w postaci ciągu &. Na przykład.

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

Zamiast "template-type='templateType'"

1

Podczas podobnego problemu wystąpił powrót do przeglądarki, która nie obsługuje interfejsu API pliku (< IE10). Kluczowa różnica polega na tym, że potrzebowałem strony, aby inteligentnie zdecydować, który szablon wyświetlić, bez korzystania z wartości atrybutu do włączenia.

Skończyłem z wykorzystaniem dostawcy constant dla mojej dyrektywy. Stałe tworzą domyślne parametry, które mogą być wstrzykiwane w dowolne miejsce w twojej dyrektywie. Po prostu pozwalam ciągłemu wywoływaniu funkcji określać obsługę przeglądarki, a następnie odwołuję się do tej wartości, gdy potrzebuję określić, który szablon przeciągnąć. To miło, ponieważ 1) nie ma żadnego atrybutu do odniesienia i 2) jest dostępny podczas fazy wstępnego połączenia, gdy nie masz dostępu do kontrolera.

(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 (...); } 
})(); 
3
templateUrl: function (elem, attrs) { 
return attrs["template"] == "table" ? 
"tableTemplate.html" : "itemTemplate.html"; 
} 
+5

Chociaż ten kod może odpowiedzieć na pytanie, podanie dodatkowego kontekstu dotyczącego tego, dlaczego i/lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość. – ryanyuyu