2013-11-20 4 views
21

Mein Ziel ist es, eine editable Richtlinie zu erstellen, die ein Benutzer HTML eines Elements das Attribut auf das bearbeiten können ist beigefügt (siehe Plunker: http://plnkr.co/edit/nIrr9Lu0PZN2PdnhQOC6)Get original transkludierte Inhalt innerhalb Winkel Richtlinie

Diese fast Werke außer Ich kann nicht das ursprüngliche unverarbeitete HTML des übersetzten Inhalts erhalten, um den Textbereich zu initialisieren. Ich kann den Text aus clone.text() bekommen, aber das fehlt die HTML-Tags wie <H1>, <div> usw. so ohne Änderungen klicken gelten nicht idempotent.

Verfahren clone.html() einen Fehler führen, Cannot read property 'childNodes' of undefined

app.directive("editable", function($rootScope) { 
    return { 
    restrict: "A", 
    templateUrl: "mytemplate.html", 
    transclude: true, 
    scope: { 
     content: "=editContent" 
    }, 

    controller: function($scope, $element, $compile, $transclude, $sce) { 

     // Initialize the text area with the original transcluded HTML... 
     $transclude(function(clone, scope) { 

     // This almost works but strips out tags like <h1>, <div>, etc. 
     // $scope.editContent = clone.text().trim(); 

     // this works much better per @Emmentaler, tho contains expanded HTML 
     var html = ""; 
     for (var i=0; i<clone.length; i++) { 
      html += clone[i].outerHTML||'';} 
     }); 
     $scope.editContent = html; 

     $scope.onEdit = function() { 
     // HACK? Using jQuery to place compiled content 
     $(".editable-output",$element).html(
      // compiling is necessary to render nested directives 
      $compile($scope.editContent)($rootScope) 
     ); 
     } 

     $scope.showEditor = false; 

     $scope.toggleEditor = function() { 
     $scope.showEditor = !$scope.showEditor; 
     }   
    } 
    } 
}); 

(Diese Frage ist im Wesentlichen ein Großschreibungs der Frage und Code nach einem frühen Versuch, die Frage zu Rahmen, Get original transcluded content in Angular directive)

+2

'clone' ist eine Sammlung von Elementen. Können Sie es in einem Debugger überprüfen? –

+0

Aha! Das Iterieren über sie und das Anfügen von outerHTML ist viel näher: 'var text =" "; für (var i = 0; i ' zeigt es '

Clock

{{time}}

'. In diesem Beispiel enthält die Uhr keinen Inhalt, daher ist der Nettoeffekt gleich. Ich frage mich, ob es möglich ist, das ursprüngliche HTML zu bekommen? – prototype

+1

Ich vermutete, dass es der Fall sein könnte. Gutes Geschäft. Der ursprüngliche HTML-Code befindet sich möglicherweise im $ element-Objekt im äußeren Bereich. Die Eingewöhnung ist nicht meine Stärke. –

Antwort

3

Die $element.innerHTML sollten enthält das ursprüngliche HTML. Ich zeige, dass es enthält

<div class="editable"> 
    <span class="glyphicon glyphicon-edit" ng-click="toggleEditor()"></span> 

    <div class="editable-input" ng-show="showEditor"> 
     <b><p>Enter well-formed HTML content:</p></b> 
     <p>E.g.<code>&lt;h1&gt;Hello&lt;/h1&gt;&lt;p&gt;some text&lt;/p&gt;&lt;clock&gt;&lt;/clock&gt;</code></p> 
     <textarea ng-model="editContent"></textarea> 
     <button class="btn btn-primary" ng-click="onEdit()">apply</button> 
    </div> 

    <div class="editable-output" ng-transclude=""></div> 
    </div> 
+3

Sehr hilfreich. Das enthält den Vorlagentext. Ihre Antwort hat mich dazu gebracht, die Methode 'compile (element, attrs)' hinzuzufügen, die das übersetzte HTML in seinem 'innerHTML' enthält. Aber es ist nach Angular erweitert es in neue DOM-Elemente mit der Vorlage. Das wird nicht funktionieren, wenn Unterelemente 'replace: true' enthalten oder Inhalte selbst enthalten. Ich vermute, es gibt keine Möglichkeit, Angular dazu zu bringen, den HTML-Code vor der Verarbeitung durch Angular zu übergeben, und somit müsste der Start-Content nicht über die Einfügung, sondern über ein Attribut oder Ajax-Bootstrapping gestartet werden. – prototype

+0

Dies kommt in den Darm des Digest-Zyklus. Wenn Sie die Priorität beliebig hoch festlegen, können Sie möglicherweise sicherstellen, dass sie zuerst ausgewertet wird. –

+0

Wie bekomme ich den nicht kompilierten Inhalt einer Angular-Direktive, wenn ich 'replace: true' mit Template verwende? es ist mein 'Element' enthält nicht den rohen ursprünglichen Inhalt, weil" Element "ein Schablonenelement und kein ursprüngliches Element ist –