2013-07-03 4 views
0

Я пытаюсь настроить директиву для обертывания компонента bootstrap popover. Моя проблема состоит в том, чтобы заставить функцию ссылок ждать, пока мой список деталей будет интерполирован.Попытка заставить мою директиву AngularJS ждать интерполяции

Чтобы сделать это мой HTML:

<div class="popover fade top in"> 
    Blah blah 
    <br /> 
    <span ng-repeat="detail in details" > 
     {{ detail.title }} 
    </span> 
</div> 

<div my-popover> 
    My text line that opens the popover on mouseover. 
</div> 

И моя директива:

portalModule.directive('myPopover', function ($compile, $interpolate) { 
    return { 
     restrict: 'A', 
     replace : false, 
     link: function (scope, element, attributes) { 
      var updateLater = function() { 
       var popoverHtml = $(element).siblings('.popover').html(); 

       var options = { 
        html: true, 
        trigger: 'hover', 
        content: popoverHtml 
       }; 

       $(element).popover(options); 
      } 

      setTimeout(updateLater, 2000); 
     } 
    } 
}); 

Это сейчас самый лучший (и единственный) способ я нашел, чтобы заставить его работать.
- Я пробовал использовать $ watch, но не мог найти, как заставить его ждать, пока весь список «деталей» будет интерполирован.
- Угловой.UI пока не управляет богатыми (html) popovers.

Любая идея/руководство по управлению этим?

[EDIT] Вот plunker (http://plnkr.co/edit/Rn2SBaiGNz4mj0F80IT3) моего вопроса с:
- новое решение (в deffer создание поповер на пользователя при наведении курсора мыши)
- Столб звено, которое остается KO

+0

Смотрите, если это помогает любому: http://stackoverflow.com/a/15179624/215945 –

+0

Здравствуйте, спасибо за ваш ответ. Я немного поиграл с этим, используя postLink, но все же KO. Я редактирую свой вопрос, чтобы добавить плункер – mpetitdant

ответ

1

I как ваше новое решение лучше, чем то, что я собираюсь представить ... но еще один способ заставить его работать - добавить директиву (eventOnLast) к вашему ng-repeat, который будет проверять на $last, а затем отправить событие, которое myPopoverLink директива может выслушать:

<li ng-repeat="detail in details" event-on-last> 

myModule.directive('eventOnLast', function($rootScope) { 
    return function(scope, element) { 
    if(scope.$last === true) { 
     element.ready(function() { 
     console.log('broadcast'); 
     $rootScope.$broadcast('event:interpolationDone'); 
     }) 
    } 
    } 
}) 
myModule.directive('myPopoverLink', function ($compile, $interpolate) { 
    return function (scope, element) { 
     scope.$on('event:interpolationDone', function() { 
     console.log('event'); 
     doPopover(element); 
     }) 
    } 
}); 

Plunker

element.ready() нужен, так что {{ detail.title }} будет интерполируется.

Кроме того, в вашем плунжере я заметил, что вы включили Angular перед jQuery. Если вы хотите, чтобы Angular использовал jQuery (а не встроенный jqLite), сначала нужно включить jQuery.

+0

Здесь вы имеете в виду, что метод 'element.ready()' будет запущен * после * интерполяция выполнена? Я прочитал исходный код 'element.ready' и нашел, что он не ведет себя так, как вы сказали ... – Xieranmaya

1

Я просто столкнулся с подобной ситуацией. Я использовал аналогичное решение для вашего, но просто использовал $ timeout-сервис. Я считаю, что код внутри функции, который передается как параметр, будет запускаться после следующего дайджеста, поэтому вам не нужно ждать 2 секунды.

$timeout(function() { 
..this will run after interpolation 
} 

Вот вы код, используя эту технику

portalModule.directive('myPopover', function ($timeout) { 
    return { 
     restrict: 'A', 
     replace : false, 
     link: function (scope, element, attributes) { 
      $timeout(function() { 

       var popoverHtml = $(element).siblings('.popover').html(); 

       var options = { 
        html: true, 
        trigger: 'hover', 
        content: popoverHtml 
       }; 

       $(element).popover(options); 
      }); 
     } 
    } 
}); 
Смежные вопросы