2017-01-24 4 views
2

Я нашел странное поведение с Angularjs. Моя директива просто добавляет и компилирует ng-repeat в мой элемент dom. Однако переменная области item недоступна. Посмотрите на код ниже для объяснения.Angularjs: Компиляция ng-repeat динамически

var demo = angular.module('demo', []); 
 
demo.directive('customRepeat', function($compile) { 
 
    return { 
 
     priority: 2000, 
 
     restrict: 'A', 
 
     compile: function(element){ 
 
     element.attr('ng-repeat', 'item in [1,2,3,4,5,6]') 
 
      
 
     return function(scope, element) { 
 
      $compile(element)(scope) 
 
     } 
 
     } 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> 
 
<div ng-app='demo'> 
 
    <h3>My Items</h3> 
 
    <div custom-repeat> 
 
     Item: {{item}} 
 
    </div> 
 
</div>

Кто имеет некоторые Angularjs навыки выясню?

N.B. Попробуйте запустить его со старой версией Angularjs (скажем, 1.2.x), и вы увидите, что она работает по назначению.

ответ

1

Правильный способ собрать директиву, когда сырье DOM модифицируются есть, создать compileFn из директивы компиляции функции, как var compileFn = $compile(element), а затем в связи функции перекомпилировать элемент с понравившейся scope. Таким образом, вы также увидите Maximum call stack exceed error как в Angular 1.2.X & версии 1.6.X. Проверьте this plunker, открыв консоль.

В основном то, что происходит это, вы добавляете ng-repeat на директиву элемента & перекомпиляции этот элемент еще раз, что приведет к составлению customDirective еще раз, и этот процесс будет продолжать бесконечно происходит. Поэтому, прежде чем компилировать элемент еще раз, вы должны убедиться, что вы удалили атрибут custom-report. Это не позволит custom-report бесконечное выполнение.

var demo = angular.module('demo', []); 
demo.directive('customRepeat', function($compile) { 
    return { 
     priority: 2000, 
     restrict: 'A', 
     compile: function(element){ 
     element.attr('ng-repeat', 'item in [1,2,3,4,5,6]') 
     element.removeAttr('custom-repeat'); 
     //this line is need for compilation of element 
     var compile = $compile(element); 
     return function(scope, element) { 
      compile(scope); //linking scope 
     } 
     } 
    } 
}); 

Plunker Demo

+0

Может быть, я не ясно. Если вы запустите код, вы увидите, что '{{item}}' не получает привязки. Он должен сказать «Item 1», «Item 2» ... и так далее. Это не вызывает никакой ошибки. – Tympanix

+0

Самое странное, как я заметил, добавив пустое выражение '{{}}' после '{{item}}', на самом деле исправляет проблему на мгновение. Это наверняка кажется ошибкой. – Tympanix

+0

@Tympanix проверить мой обновленный ответ с демонстрацией plunker .. надеюсь, что теперь это ясно. –