Ich erstelle eine AngularJS-Direktive <row>
, Die sich selbst ersetzen muss (das Tag <row>
Darf nach der Ausführung nicht im DOM vorhanden sein) durch eine dynamische Vorlage, die beliebigen HTML-Code enthalten kann.
Das Problem bei der Verwendung von replace: true
Ist, dass es nicht mit den <tr>
- Tags der Tabelle funktioniert und dass die Vorlage dynamisch ausgewählt wird.
Ich versuche also, einen Weg zu finden, um das Element in der Verknüpfungsfunktion zu ersetzen, ohne Erfolg.
Wenn Sie die Funktion .replaceWith()
von jQuery verwenden, wird ngRepeat
aus einem unbekannten Grund unterbrochen.
Irgendwelche Hinweise?
Hier ist die Geige
Ihre Geige scheint ziemlich einfach, aber Sie sollten in der Lage sein, nur outerHTML
zu verwenden
element[0].outerHTML ='<div>I should not be red</div>';
Wenn Sie mit ng-repeat
Arbeiten müssen, können Sie Ihre Elemente an eine Bereichseigenschaft binden und sie in Ihrer kompilierten Vorlage referenzieren. Sobald es kompiliert ist, können Sie jQuery replaceWith()
verwenden.
html
<row items="items">***</row>
richtlinie
.directive('row', function ($compile) {
return {
restrict: 'E',
scope: {
items: "="
},
link: function (scope, element, attrs) {
var html ='<div ng-repeat="item in items">I should not be red</div>';
var e =$compile(html)(scope);
element.replaceWith(e);
}
};
});
Marks Antwort wird funktionieren, aber dieses Beispiel ist zu begrenzt, um das ganze Bild zu zeigen. Während Marks Direktive in der Tat für gemeinsame und einfache UI-Komponenten ausreicht, sollte dieses Muster für komplexere Operationen vermieden werden. Im Folgenden erkläre ich ausführlich den Grund dafür. Tatsächlich bietet Angular bereits eine weitaus einfachere Möglichkeit, das Direktivenelement durch eine Vorlage zu ersetzen am Ende dieser Antwort.
So sieht eine Direktive hinter den Kulissen aus:
.directive('row', function ($compile) {
return {
restrict: 'E',
scope: {
items: "="
},
// Whether you define it this way or not, this is the order of
// operation (execution) behind every AngularJS directive.
// When you use the more simple syntax, Angular actually generates this
// structure for you (this is done by the $compile service):
compile: function CompilingFunction($templateElement, $templateAttributes, transcludeFn) {
// The compile function hooks you up into the DOM before any scope is
// applied onto the template. It allows you to read attributes from
// the directive expression (i.e. tag name, attribute, class name or
// comment) and manipulate the DOM (and only the DOM) as you wish.
// When you let Angular generate this portion for you, it basically
// appends your template into the DOM, and then some ("some" includes
// the transclude operation, but that's out of the $scope of my answer ;) )
return function LinkingFunction($scope, $element, $attrs) {
// The link function is usually what we become familiar with when
// starting to learn how to use directives. It gets fired after
// the template has been compiled, providing you a space to
// manipulate the directive's scope as well as DOM elements.
var html ='<div ng-repeat="item in items">I should not be red</div>';
var e = $compile(html)($scope);
$element.replaceWith(e);
};
}
};
});
Was können wir daraus machen? Es ist dann offensichtlich, dass der manuelle Aufruf von $compile
für dasselbe DOM-Layout zweimal ist redundant, schlecht für die Leistung und Auch schlecht für deine Zähne. Was solltest du stattdessen tun? Kompilieren Sie einfach Ihr DOM, wo es kompiliert werden soll :
.directive('row', function ($compile) {
return {
restrict: 'E',
template: '<div ng-repeat="item in items">I should not be red</div>',
scope: {
items: "="
},
compile: function CompilingFunction($templateElement, $templateAttributes) {
$templateElement.replaceWith(this.template);
return function LinkingFunction($scope, $element, $attrs) {
// play with the $scope here, if you need too.
};
}
};
});
Wenn Sie weiter unter der Haube von Richtlinien eintauchen möchten, bezeichne ich dies als inoffizielle AngularJS-Direktivenreferenz
Sobald Sie hier fertig sind: https: //github.com/angular/angular.js/wiki/Understanding-Directives
Mit replace: true
:
.directive('row', function ($compile) {
return {
restrict: 'E',
template: '<div ng-repeat="item in items">I should not be red</div>',
replace: true,
scope: {
items: "="
}
};
});