5

In der angular documentation for the compile service (starting at line 412) gibt es eine Beschreibung der Transclude-Funktion, die in die Verknüpfungsfunktion einer Direktive übergeben wird.Wie wird "futureParentElement" in der transclude-Funktion einer directive link-Funktion verwendet?

Der relevante Teil lautet:

function([scope], cloneLinkingFn, futureParentElement) 

in denen (Leitung 212):

futureParentElement: definiert den Elternteil zu dem die cloneLinkingFn die klonierten Elemente hinzugefügt werden.

  • default: $element.parent() resp. $element für transclude:'element' resp. transclude:true.

  • nur für transcludes benötigt, die nicht HTML-Elemente dürfen enthalten (zB SVG-Elemente) und wenn die cloneLinkinFn übergeben wird, als jene Elemente müssen in besonderer Weise erstellt und geklont, wenn sie sich außerhalb ihrer üblichen definiert sind Behälter (zB wie <svg>).

  • Siehe auch die directive.templateNamespace Eigenschaft.

ich nicht den Punkt der futureParentElement jedoch zu sehen. Es heißt

definiert das übergeordnete Element, zu dem cloneLinkingFn die geklonten Elemente hinzufügen wird.

Aber Sie tun das in der cloneLinkingFn sich wie folgt aus:

transclude(scope, function (clone) { 
    some_element.append(clone); 
}); 

Und Sie nicht die transcluden Funktion ohne zu definieren, die das Klonen Funktion in erster Linie nutzen können.

Was ist die richtige Verwendung/eine Verwendung für futureParentElement?

Antwort

6

Die Antwort auf diese kann durch einen Blick auf den Sport git blame of compile.js finden: dass der Commit futureParentElement hinzugefügt https://github.com/angular/angular.js/commit/ffbd276d6def6ff35bfdb30553346e985f4a0de6

Im begehen gibt es einen Test, der eine Richtlinie svgCustomTranscludeContainer

directive('svgCustomTranscludeContainer', function() { 
    return { 
    template: '<svg width="400" height="400"></svg>', 
    transclude: true, 
    link: function(scope, element, attr, ctrls, $transclude) { 
     var futureParent = element.children().eq(0); 
     $transclude(function(clone) { 
     futureParent.append(clone); 
     }, futureParent); 
    } 
    }; 
}); 

durch Test prüft wie die Erstellung der hTML-<svg-custom-transclude-container><circle cx="2" cy="2" r="1"></circle> verhält:

it('should handle directives with templates that manually add the transclude further down', inject(function() { 
    element = jqLite('<div><svg-custom-transclude-container>' + 
     '<circle cx="2" cy="2" r="1"></circle></svg-custom-transclude-container>' + 
     '</div>'); 
    $compile(element.contents())($rootScope); 
    document.body.appendChild(element[0]); 

    var circle = element.find('circle'); 
    assertIsValidSvgCircle(circle[0]); 
})); 

Es sieht also so aus, als ob Sie ein SVG-Bild mit einer Direktive erstellen, deren Vorlage den eingeschlossenen SVG-Inhalt in <svg> ... </svg> Tags umwandelt, dann ist dieses SVG-Bild nicht gültig (durch irgendeine Definition), wenn Sie nicht das korrekte futureParentElement an $transclude übergeben .

Um zu sehen, was es bedeutet, nicht gültig zu sein, über den Test im Quellcode hinaus, erstellte ich 2 Direktiven basierend auf denen im Komponententest, und versuchte sie, ein SVG-Bild mit Teilkreis zu erstellen . Einer der futureParentElement mit:

<div><svg-custom-transclude-container-with-future><circle cx="1" cy="2" r="20"></circle></svg-custom-transclude-container></div> 

und eine, die identisch ist, aber das bedeutet nicht:

<div><svg-custom-transclude-container-without-future><circle cx="2" cy="2" r="20"></circle></svg-custom-transclude-container></div> 

Wie bei http://plnkr.co/edit/meRZylSgNWXhBVqP1Pa7?p=preview zu sehen ist, der mit dem futureParentElement zeigt den Teilkreis, und die eine ohne nicht. Die Struktur des DOM erscheint identisch. Chrome scheint jedoch zu berichten, dass das zweite circle Element kein SVG-Knoten, sondern ein einfacher HTML-Knoten ist.

Also was auch immer futureParentElement tatsächlich unter der Haube tut, scheint es sicherzustellen, dass übergelagerter SVG-Inhalt schließlich als SVG vom Browser behandelt wird.

+0

So ist es irrelevant für HTML-Inhalt, nicht wahr? – krave

+0

@krave Ich glaube schon: "nur für transcludes benötigt, die nicht html Elemente enthalten dürfen" –