Właśnie zaczynam od angularjs i pracuję nad konwersją kilku starych wtyczek JQuery do dyrektyw Angular. Chciałbym zdefiniować zestaw domyślnych opcji dla dyrektywy my (element), które można przesłonić, podając wartość opcji w atrybucie.
Rozejrzałem się po tym, jak zrobili to inni, iw bibliotece angular -ui plik ui.bootstrap.pagination wydaje się robić coś podobnego.
Najpierw wszystkie domyślne opcje są zdefiniowane w stałym obiekcie:
.constant('paginationConfig', {
itemsPerPage: 10,
boundaryLinks: false,
...
})
Następnie getAttributeValue
do kontrolera dyrektywy dołączana jest funkcja użyteczności:
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
return (angular.isDefined(attribute) ?
(interpolate ? $interpolate(attribute)($scope.$parent) :
$scope.$parent.$eval(attribute)) : defaultValue);
};
Na koniec jest to używane w funkcji łączenia do wczytywania atrybutów jako
.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
...
controller: 'PaginationController',
link: function(scope, element, attrs, paginationCtrl) {
var boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks, config.boundaryLinks);
var firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true);
...
}
});
Wydaje się, że jest to dość skomplikowana konfiguracja w przypadku czegoś tak standardowego, jak chęć zastąpienia zestawu wartości domyślnych. Czy istnieją inne popularne sposoby na zrobienie tego? A może to normalne, że zawsze definiuje się funkcję narzędzia, taką jak getAttributeValue
i analizuje opcje w ten sposób? Jestem zainteresowany, aby dowiedzieć się, jakie różne strategie mają ludzie dla tego wspólnego zadania.
Dodatkowo, jako bonus, nie rozumiem, dlaczego ten interpolate
parametr jest wymagany.
źródło
ui.bootstrap.pagination
sprawy są bardziej skomplikowane? Pomyślałem, że jeśli użyjesz funkcji kompilacji, wszelkie zmiany atrybutów dokonane później nie zostaną odzwierciedlone, ale to nie wydaje się być prawdą, ponieważ na tym etapie są ustawione tylko wartości domyślne. Chyba musi nastąpić jakiś kompromis.compile
nie można odczytać atrybutów, które powinny być interpolowane, aby uzyskać wartość (która zawiera wyrażenie). Ale jeśli chcesz sprawdzić tylko czy atrybut jest pusty - będzie działał bez żadnych kompromisów (przed interpolacją atrybut będzie zawierał łańcuch z wyrażeniem).ui.bootstrap.pagination
przykładzie, znalazłem ten bardzo przydatny przykład: jsfiddle.net/EGfgHlink
opcji, nadal możesz zwrócić funkcję w swojejcompile
opcji. doc tutajattributes.foo = '["one", "two", "three"]'
zamiastattributes.foo = ["one", "two", "three"]
Użyj
=?
flagi dla właściwości w bloku zakresu dyrektywy.źródło
=?
jest dostępny od 1.1.xtrue
lubfalse
jako wartości, chciałbyś (myślę) użyć np$scope.hasName = angular.isDefined($scope.hasName) ? $scope.hasName : false;
. Zamiast tego.=?
, ale nie z obowiązującymi jednokierunkowe@?
.link
funkcji? W oparciu o moje zrozumienie, przypisywanie w trakcielink
powinno unikać$scope.$apply()
cyklu, prawda?Używam AngularJS v1.5.10 i stwierdziłem, że
preLink
funkcja kompilacji działa raczej dobrze przy ustawianiu domyślnych wartości atrybutów.Tylko przypomnienie:
attrs
przechowuje nieprzetworzone wartości atrybutów DOM, które są zawsze alboundefined
ciągami albo ciągami.scope
przechowuje (między innymi) wartości atrybutów DOM przeanalizowane zgodnie z podaną specyfikacją zakresu izolowania (=
/<
/@
/ itp.).Skrócony fragment:
źródło