Подтвердить что ты не робот

Ng-repeat в сочетании с пользовательской директивой

У меня возникла проблема с использованием директивы ng-repeat в сочетании с моей собственной настраиваемой директивой.

HTML:

<div ng-app="myApp">
  <x-template-field x-ng-repeat="field in ['title', 'body']" />
</div>

JS:

angular.module('myApp', [])
    .directive('templateField', function () {
        return {
            restrict: 'E',
            compile: function(element, attrs, transcludeFn) {
                element.replaceWith('<input type="text" />');
            }
        };
    });

Смотрите этот скрипт JS: http://jsfiddle.net/GDfxd/

Проблема в том, что ничего не заменяется. То, что я пытаюсь выполнить, - выход из 2x полей ввода, причем теги "x-template-field" полностью заменены в DOM. Мое подозрение в том, что поскольку ng-repeat одновременно модифицирует DOM, это не сработает.

Согласно this вопросу о переполнении стека, принятый ответ, похоже, указывает, что это действительно работало в более ранних версиях AngularJS (?).

Не работает ли element.html('...')?

В то время как element.html('...') фактически внедряет сгенерированный HTML в целевой элемент, я не хочу, чтобы HTML как дочерний элемент тега шаблона, а скорее заменил его полностью в DOM.

Почему я не обертываю тег шаблона другим тегом, у которого есть директива ng-repeat?

В основном по той же причине, что и выше, я не хочу, чтобы мой сгенерированный HTML в качестве дочернего элемента повторялся. Хотя это, вероятно, будет работать прилично в моем приложении, я все равно буду чувствовать, что адаптировал свою разметку для соответствия Angular, а не наоборот.

Почему я не использую свойство "template"?

Я не нашел способа изменить HTML, полученный из свойств 'template'/'templateUrl'. HTML, который я хочу ввести, не является статическим, он динамически генерируется из внешних данных.

Неужели я слишком разборчив с моей разметкой?

Возможно.: -)

Любая помощь приветствуется.

4b9b3361

Ответ 1

Ваша директива должна выполняться до ng-repeat с использованием более высокого приоритета, поэтому, когда ng-repeat клонирует элемент, он может выбрать ваши модификации.

В разделе "Причины разделения компиляции/ссылки" из руководство пользователя директив есть объяснение того, как работает ng-repeat.

текущий ng-repeat приоритет - 1000, поэтому все, что выше этого, должно это сделать.

Таким образом, ваш код будет выглядеть следующим образом:

angular.module('myApp', [])
    .directive('templateField', function () {
        return {
            restrict: 'E',
            priority: 1001, <-- PRIORITY
            compile: function(element, attrs, transcludeFn) {
                element.replaceWith('<input type="text" />');
            }
        };
});

Ответ 2

Поместите свой ng-repeat в шаблон. Вы можете изменять атрибуты элемента и, соответственно, в директиве, чтобы определить, требуется ли ng-repeat или какие данные использовать внутри компиляции директивы

HTML (атрибут):

<div ng-app="myApp" template-field></div>

JS:

angular.module('myApp', [])
    .directive('templateField', function () {
        return {          
            restrict: 'A',
            template:'<input type="text" value="{{field}" ng-repeat="field in [\'title\',\'body\']" />'            
        };
    });

DEMO: http://jsfiddle.net/GDfxd/3/

Также работает как элемент:

HTML (элемент):

<div ng-app="myApp" >
    <template-field/>
</div>

JS

angular.module('myApp', [])
    .directive('templateField', function () {
        return {          
            restrict: 'E',
            replace:true,
            template:'<input type="text" value="{{field}}" ng-repeat="field in [\'title\',\'body\']" />'

        };
    });

DEMO: http://jsfiddle.net/GDfxd/3/