2014-01-09 81 views
0

我有一個像這樣的指令,它用一個容器包裝元素。包裝時的angularjs指令的奇怪行爲

app.directive('myDirective', function($compile, $timeout) { 
    var num=0; 
    return { 
    link: function(scope, el, attrs) { 
     var uniqNum = scope.$index || num++; 
     var container = document.createElement('div'); 
     container.className = "container"; 
     el.wrap(container); 
    } 
    }; 
}); 

<textarea my-directive ng-repeat="str in arr track by $index" ng-model="arr[$index]"> 
</textarea> 

然而,正如你在演示中,http://plnkr.co/edit/wOulzF?p=preview,當你開始輸入到文本區域看,元素去容器外。

如果ng-model不是arr,它可以正常工作。

任何人都可以解釋這種行爲?

回答

1

您的指令在ngRepeat之前運行。當Angular編譯一個ngRepeat時,它會在它用作標記的代碼中放置特殊註釋。由於您的指令在添加到DOM之前正在運行,因此您的包裝並未包含這些重要的評論。相反,最初創建的HTML看起來像這樣:

<!-- ngRepeat: str in arr track by $index --> 
<div class="container"> 
    <textarea my-directive="" ng-repeat="str in arr track by $index" ng-model="arr[$index]" class="ng-scope ng-pristine ng-valid"> </textarea> 
</div> 
<!-- end ngRepeat: str in arr track by $index --> 

arr隨後改變了ngRepeat更新DOM將新的/更新ngRepeat元素,其中角的標記(評論)是 - 這是您的包裝外面。所以,arr改變後(和$摘要發生時)你的HTML看起來像這樣:

<!-- ngRepeat: str in arr track by $index --> 
    <textarea my-directive="" ng-repeat="str in arr track by $index" ng-model="arr[$index]" class="ng-scope ng-pristine ng-valid"> </textarea> 
    <div class="container"> </div> 
<!-- end ngRepeat: str in arr track by $index --> 

爲了解決這個問題設置你的指令優先級爲1001以上(ngRepeat有1000優先級):

return { 
    priority: 1001, 
    link: function(scope, el, attrs) {.. } 
} 

現在ngRepeat將操作DOM第一所以當你的指令包裹元素ngRepeat評論將被包裹得產生下面的HTML:

<div class="container"> 
    <!-- ngRepeat: str in arr track by $index --> 
    <textarea my-directive="" ng-repeat="str in arr track by $index" ng-model="arr[$index]" class="ng-scope ng-pristine ng-valid"> </textarea> 
    <!-- end ngRepeat: str in arr track by $index --> 
</div> 

和修復您的問題 - updated plunker

1

對於您的textarea,您使用的模型與您的ng-repeat相同。這意味着如果您更改textarea的內容,則同時更改ng-repeat指令的型號。這又導致ng-repeat再次忙碌起來。

+0

我添加刪除NG-repleat,'EL [0] .removeAttribute( 'NG重複')',但我沒有看到任何進展。 – allenhwkim