2014-01-09 4 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-модель не оборная, она работает нормально.

Любой может объяснить это поведение?

ответ

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 элемента, где маркер углового (в комментарии) IS-, которая за пределами обертки. Таким образом, после того, как 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

Я добавил, чтобы удалить нг-repleat, 'эль [0] .removeAttribute ('нг-повтора')', но я не вижу никакого прогресса. – allenhwkim

Смежные вопросы