2015-03-06 1 views
2

This fiddle должны сделать вещи более ясно, но по сути я назначаю некоторые атрибуты элемента (например, его идентификатор) параметры в своей директиве:Как я могу избежать условий гонки при запуске, когда атрибуты директивы интерполируются?

myApp.directive('myDiv', function() { 
return { 
    restrict: 'E', 
    replace: true, 
    scope: { 
     'elementId': '@', 
     'displayName': '@', 
    }, 
    transclude: true, 
    template: '<div class="my-div" id="{{elementId}}">{{displayName}}<div ng-transclude></div></div>' 
} 

})

Проблема заключается в том, если я сразу делать вещи при запуске, как и инициализация других директив, эти значения (например, elementId) еще не интерполированы.

Другими словами, если я получаю ссылку на элемент myDiv и распечатываю свой идентификатор, сразу при запуске печатается «{{elementId}}». Но если я подожду короткое время (скажем, одну секунду), то значение, которое было передано как значение атрибуту element-id, напечатано (как и ожидалось).

Если вы откроете консоль во время просмотра скрипта, вы увидите это.

Что я здесь делаю неправильно? Как я могу избежать этого (кроме многих действительно уродливых тайм-аутов при запуске)?

+0

Вы посмотрели на ng-cloak? –

+0

@JoeEnzminger - Я использовал его раньше, но это не проблема отображения. Мой пример значительно упрощен, но общая идея заключается в том, что при первом входе в файл elementId он регистрируется в другой службе. Поэтому вместо того, чтобы пытаться зарегистрировать себя с собственным идентификатором, он регистрируется с помощью «{{elementId}}». Я не думаю, что здесь будет применяться ng-cloak, но дайте мне знать, если я что-то упустил. – Jer

ответ

2

У вас есть несколько неправильных вещей. Вот новая скрипка, в которой вы можете увидеть журнал «сначала», указав правильное значение: http://jsfiddle.net/0mq2xv8m/

1) Вы должны включить внутренний элемент в шаблон второго. У вас есть transclude set to true, поэтому он заменит ваш узел. Это также гарантирует, что вторая директива не будет связываться до того, как первая будет готова. То есть так как он находится в DOM вместе с директивой outter, он может не выполнять действия с директивой об упаковке.

template: '<div class="my-div" id="elementId">{{displayName}}<div my-field></div></div>' 

2) делать id="elementId" вместо id="{{elementId}}" пройти по ссылке, а значения

3), как правило, это плохая практика ловить атрибуты родителя, то лучше пройти его с обязательным 2-полосным , Это справедливо для любого ориентированного на список программирования, с которым я работал.

Good Practice:

Вы должны использовать контроллер или функции связи для любых "INIT" шагов. Они не будут выполняться до тех пор, пока директива не свяжет все свои атрибуты/область. То, как вы это делаете, выполняется во время этапа оценки при создании $ scope (пока еще нет области). Функции связи и контроллеры ждут появления $ scope. Вместо функции связи можно использовать контроллер (я думаю, что это более ясный и простой для модульного теста).

angular.module('App').controller('someController',[], function() { 
     var controller = { 
      init:function(){ 
       console.log(elementId); 
      } 
     } 
     controller.init(); 
     return controller; 
}); 


myApp.directive('myDiv', function() { 
return { 
    restrict: 'E', 
    replace: true, 
    controller:'someController', 
    scope: { 
     'elementId': '@', 
     'displayName': '@', 
    }, 
    transclude: true, 
    template: '<div class="my-div" id="{{elementId}}">{{displayName}}<div ng-transclude></div></div>' 
} 
+0

Спасибо. Я попытался изменить функцию, которую я возвращаю к функции связывания, но я получаю такое же поведение. А также в вашем примере, я не понимаю, почему контроллер должен иметь доступ к переменной под названием 'elementId'. Какова связь между переменными области видимости директивы и доступом к ее контроллеру? – Jer

+0

Я читал немного больше, и кажется, что возвращение функции, как я, это просто сокращение для функции ссылки. – Jer

+0

Я нашел вашу проблему, см. Обновленный ответ. – FlavorScape