In Fällen, in denen Sie mehrere Anweisungen für ein einzelnes DOM-Element haben und die Reihenfolge, in der sie angewendet werden, von Bedeutung ist, können Sie die priority
Eigenschaft verwenden, um ihre Anwendung zu ordnen. Höhere Zahlen laufen zuerst. Die Standardpriorität ist 0, wenn Sie keine angeben.
EDIT : Nach der Diskussion ist hier die vollständige Arbeitslösung. Der Schlüssel bestand darin , das Attribut zu entfernen : element.removeAttr("common-things");
, und auch element.removeAttr("data-common-things");
(falls Benutzer data-common-things
im HTML angeben )
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true, //this setting is important, see explanation below
priority: 1000, //this setting is important, see explanation below
compile: function compile(element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
$compile(iElement)(scope);
}
};
}
};
});
Der funktionierende Plunker ist verfügbar unter: http://plnkr.co/edit/Q13bUt?p=preview
Oder:
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
link: function link(scope,element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
$compile(element)(scope);
}
};
});
DEMO
Erklärung warum wir setzen müssen terminal: true
und priority: 1000
(eine hohe Zahl):
Wenn das DOM bereit ist, geht Angular durch das DOM, um alle registrierten Anweisungen zu identifizieren und die Anweisungen einzeln zu kompilieren, basierend darauf, priority
ob sich diese Anweisungen auf demselben Element befinden . Wir setzen unsere Priorität der benutzerdefinierten Richtlinie auf eine hohe Zahl , um sicherzustellen , dass es kompiliert werden erste und terminal: true
werden die anderen Richtlinien werden übersprungen , nachdem diese Richtlinie kompiliert wird.
Wenn unsere benutzerdefinierte Direktive kompiliert wird, ändert sie das Element, indem sie Direktiven hinzufügt und sich selbst entfernt, und verwendet den $ compile-Dienst, um alle Direktiven (einschließlich der übersprungenen) zu kompilieren .
Wenn wir das nicht tun gesetzt terminal:true
und priority: 1000
, gibt es eine Chance , dass einige Richtlinien zusammengestellt werden , bevor unsere eigene Richtlinie. Und wenn unsere benutzerdefinierte Direktive $ compile verwendet, um das Element zu kompilieren => kompilieren Sie die bereits kompilierten Direktiven erneut. Dies führt zu unvorhersehbarem Verhalten, insbesondere wenn die vor unserer benutzerdefinierten Anweisung kompilierten Anweisungen das DOM bereits transformiert haben.
Weitere Informationen zu Priorität und Terminal finden Sie unter Wie verstehe ich das Terminal der Richtlinie?
Ein Beispiel für eine Direktive, die auch die Vorlage ändert, ist ng-repeat
(Priorität = 1000). Wenn diese ng-repeat
kompiliert wird, ng-repeat
erstellen Sie Kopien des Vorlagenelements, bevor andere Direktiven angewendet werden .
Dank des Kommentars von @ Izhaki ist hier der Verweis auf den ngRepeat
Quellcode: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
RangeError: Maximum call stack size exceeded
Es wird für immer kompiliert.