2013-12-16 3 views
1

Вот код: linkAngularJS: Как правильно перевести дочерние элементы в пользовательскую директиву?

Я пытаюсь создать директиву, которая обертывает своих детей в какой-нибудь шаблон. Но если у детей есть ng-if, контролирующих их внешний вид, «переключение» не работает. Ну, это вроде как, но, как вы видите, логика ng-if не проходит правильно.

Я хотел бы знать, как это исправить, но также и где (если где угодно) это описано в документах Angular.

ответ

2

Проблема заключается в том, что Angular изначально заменяет ngIf комментатором, который используется для отслеживания места размещения условного кода. Это проще всего увидеть на примере.

Ваш HTML:

<div control-group> 
    <label>Test</label> 
    <input type="text" ng-model="editing.name" /> 
    <span class="text-error" ng-if="editing.name.length != 3"> Name must be 3 characters </span> 
</div> 

Похоже, это внутри вашей transclude функция в cloned переменной (transclude(function (cloned) {):

<div control-group> 
    <label>Test</label> 
    <input type="text" ng-model="editing.name" class="ng-valid ng-dirty"> 
    <!-- ngIf: editing.name.length != 3 --> 
</div> 

Итак, элемент с классом text-error, что вы фильтрации на (ниже) не находится в cloned. Просто комментарий есть.

var inputsAndMessages = cloned.filter('input, button, select, .text-error'); 

Поскольку вы только transcluding элементов, которые соответствуют выше ФИЛЬТРУ ngIf комментария теряются.

Решение является фильтрация для комментариев, а также и добавить их в Append (так Угловая поддерживает это точка отсчета в ngIf). Один из способов сделать это, чтобы заменить выше этого (используя тот факт, что HTML комментарий тип узла 8)

var messages = cloned.filter(function(){ return this.nodeType == 8; }); //comments 

var inputs = cloned.filter('input, button, select') 

var inputsAndMessages = inputs.add(messages); 

Working plunker

+0

Хорошо, это работает - вы объяснили, что происходит.Я думаю, в реальном коде, так как я не знаю, будет ли 'ng-if' на подэлементе или нет, мне нужно установить определение директивы' terminal: true' и сам 'comp compile' , Таким образом, я могу переделать элементы перед компиляцией 'ng-if' get и превратить в комментарий. –

2

Вы должны указать директиву, где разместить дочерние элементы с ng-transclude директивы: (plnkr)

template: "<div class='control-group' ng-transclude>" + 
       "<label class='control-label' for=''></label>" + 
       "<div class='controls'></div>" + 
       "</div>", 

Из документов:

Директива, которая отмечает точку вставки включены через DOM ближайшей родительской директивы, которая использует переход.

Любое существующее содержимое элемента, на которое установлена ​​эта директива, будет удалено до того, как будет вставлен переводный контент.

Я не был уверен, что именно ваше намерение было, так как у вас есть input и label как в шаблоне и как дети в HTML. Возможно, вы захотите разместить свой ng-transclude в другом месте.

+0

Я не могу использовать 'нг-transclude', потому что я хочу переведите мои дочерние элементы ввода в разные точки шаблона. Поэтому мне нужно использовать более гибкие функции 'translude'. Вероятно, я должен добавить этот вопрос к моему вопросу. –

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