2013-11-20 71 views
21

我的目標是創建一個editable指令,允許用戶修改該屬性附加任何元素的HTML(見Plunker:http://plnkr.co/edit/nIrr9Lu0PZN2PdnhQOC6獲取角指令中原來transcluded內容

幾乎作品除我無法獲取原文的原始HTML轉換內容來初始化文本區域。我可以從clone.text()獲得它的文本,但是缺少如<H1>,<div>等HTML標記,因此單擊應用而不進行編輯並不是冪等的。

方法clone.html()引發錯誤,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; 
     }   
    } 
    } 
}); 

(這個問題本質上是較早嘗試到幀的問題後的問題和代碼的批發重寫,Get original transcluded content in Angular directive

+2

'clone'是一個元素的集合。你是否能夠在調試器中檢查它? –

+0

啊哈!遍歷它們並附加outerHTML更接近:'var text =「」; for(var i = 0; i '它顯示'

Clock

{{time}}

'。在這個例子中,時鐘不會傳輸內容,所以實際效果是一樣的。我想知道是否有可能獲得原始的HTML? – prototype

+1

我懷疑它可能是這種情況。好交易。原始HTML可能位於外部作用域中的$ element對象中。包容並不是我的強項。 –

回答

3

$element.innerHTML應包含原始的HTML。我顯示它包含

<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

非常有幫助。包含模板文本。你的回答確實激發我添加了在其innerHTML中包含HTML的方法'compile(element,attrs)'。但是在Angular使用模板將其擴展到新的DOM元素之後。如果有任何子元素具有'replace:true'或者自己跨越內容,那麼這將會中斷。我懷疑沒有辦法讓Angular在Angular處理它之前給出HTML,因此開始的內容不需要通過跨越來引導,而是通過屬性或者ajax來傳遞。 – prototype

+0

這進入了摘要循環的內涵。通過將優先級設置爲任意高,您可以確保首先對其進行評估。 –

+0

如果我在模板中使用'replace:true',如何獲得Angular指令的未編譯transclude內容。這意味着'element'不包含原始內容,因爲'element'是模板元素而不是原始元素 –