2015-05-12 2 views
0

У меня есть раздел в моем html, где я загружаю отзывы, и я использую flexslider на нем.Директива AngularJS, ng-repeat и JQuery Plugin

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

<section class="testimonials"> 
<div class="row"> 
    <div class="small-12 column"> 
     <div class="flexslider"> 
      <ul class="slides"> 
       <li> 
        <h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod</h2> 
        <span>- Author Name</span> 
       </li> 
       <li> 
        <h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod</h2> 
        <span>- Author Name</span> 
       </li> 
       <li> 
        <h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit</h2> 
        <span>- Author Name</span> 
       </li> 
       <li> 
        <h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod</h2> 
        <span>- Author Name</span> 
       </li> 
       <li> 
        <h2>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod</h2> 
        <span>- Author Name</span> 
       </li> 
      </ul> 
     </div> 
     <div class="author-thumbs"> 
      <ul class="slides"> 
       <li> 
        <div> 
         <span class="container"> 
          <img src="assets/img/testimonial-author-pic.jpg" alt=""> 
         </span> 
        </div> 
       </li> 
       <li> 
        <div> 
         <span class="container"> 
          <img src="assets/img/testimonial-author-pic.jpg" alt=""> 
         </span> 
        </div> 
       </li> 
       <li> 
        <div> 
         <span class="container"> 
          <img src="assets/img/testimonial-author-pic.jpg" alt=""> 
         </span> 
        </div> 
       </li> 
       <li> 
        <div> 
         <span class="container"> 
          <img src="assets/img/testimonial-author-pic.jpg" alt=""> 
         </span> 
        </div> 
       </li> 
      </ul> 
     </div> 
    </div> 
</div> 

Сначала я попал в беду, потому что с Угловое была загрузка частичного файла после того, как документ был готов, мои ползунки перестали работать. Поэтому я переместил инициализацию flexslider в директиву. Например:

app.directive('testimonials', function() { 
return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 
     element.find('.author-thumbs').flexslider({ 
      animation: "slide", 
      controlNav: "thumbnails", 
      controlNav: false, 
      directionNav: false, 
      itemWidth: 80, 
      minItems: 4, 
      maxItems: 4, 
      asNavFor: ".testimonials .flexslider", 
     }); 
     element.find('.flexslider').flexslider({ 
      animation: "slide", 
      controlNav: "thumbnails", 
      controlNav: false, 
      directionNav: false, 
      smoothHeight: true, 
      sync: ".testimonials .author-thumbs" 
     }); 
    } 
}; 
}); 

Таким образом, я получил его для работы с добавлением отзывов в разделе html.

Хорошо, но теперь я хочу взять это статическое содержимое и перенести его на свой контроллер и сделать ng-repeat. Так что я сделал это:

app.controller('HomeCtrl', function($scope){ 
    $scope.testimonials = [ 
     {"quote":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod", "author":"Author Name", "img":"assets/img/testimonial-author-pic.jpg"}, 
     {"quote":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit.", "author":"Author Name", "img":"assets/img/testimonial-author-pic.jpg"}, 
     {"quote":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod", "author":"Author Name", "img":"assets/img/testimonial-author-pic.jpg"}, 
     {"quote":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod", "author":"Author Name", "img":"assets/img/testimonial-author-pic.jpg"}, 
    ] 
}); 

Создан новый файл для свидетельства раздела разметки и изменили это директива быть типа E:

app.directive('testimonials', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     templateUrl: 'partials/elements/testimonials.html', 
     link: function(scope, element, attrs) { 
      element.find('.author-thumbs').flexslider({ 
       animation: "slide", 
       controlNav: "thumbnails", 
       controlNav: false, 
       directionNav: false, 
       itemWidth: 80, 
       minItems: 4, 
       maxItems: 4, 
       asNavFor: ".testimonials .flexslider", 
      }); 
      element.find('.flexslider').flexslider({ 
       animation: "slide", 
       controlNav: "thumbnails", 
       controlNav: false, 
       directionNav: false, 
       smoothHeight: true, 
       sync: ".testimonials .author-thumbs" 
      }); 
     } 
    }; 
}); 

А теперь ... Ну, теперь отзывы появляются но flexslider не инициализируется. Кто-нибудь знает, что я сделал неправильно? Я ищу и отвечаю, что может объяснить, ПОЧЕМУ, что я сделал, неправильно, так как я пытаюсь это изучить.

Я бегу angularjs 1.3.15

ответ

2

мне удалось получить эту работу оберточной инициализацию FlexSlider внутри $ таймаута, например:

app.directive('testimonials', function($timeout) { 
    return { 
     restrict: 'E', 
     replace: true, 
     templateUrl: 'partials/elements/testimonials.html', 
     link: function(scope, element, attrs) { 
      $timeout(function(){ 
       element.find('.author-thumbs').flexslider({ 
        animation: "slide", 
        controlNav: "thumbnails", 
        controlNav: false, 
        directionNav: false, 
        itemWidth: 80, 
        minItems: 4, 
        maxItems: 4, 
        asNavFor: ".testimonials .flexslider", 
       }); 
       element.find('.flexslider').flexslider({ 
        animation: "slide", 
        controlNav: "thumbnails", 
        controlNav: false, 
        directionNav: false, 
        smoothHeight: true, 
        sync: ".testimonials .author-thumbs" 
       }); 
      }); 
     } 
    }; 
}); 

Что происходит, так как моя переменная отзывы жестко закодировано Мне нужно $ timeout для запуска javascript после того, как все будет загружено.

Когда я меняю его, чтобы загрузить отзывы с сервера, $ watch, вероятно, будет лучшим решением, например, предложенным Денисом Смолеком, потому что произойдет фактическое изменение характеристик, вызвав запуск flexlider init. Я не уверен на 100%, так как я еще не тестировал его, но я твердо верю, что это сработает. Я обновлю этот ответ, когда сделаю изменения и протестирую его

0

Итак, вы обнаружите, что когда вы обновляете свой контент в ng-repeat, ваши слайды, вероятно, будут работать неправильно, поскольку они не будут прикреплены к вызову flexslider, но Я не пробовал flexslider/Angular.

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

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

Я хотел бы сделать $ часы и настройки функции:

function setupFlexslider() { 
    //your flexslider code 
} 
$scope.$watch('testimonials', function(newData,oldData) { 
    if(newData){ 
     setupFlexslider(); 
    } 
} 

Так что это будет срабатывать при заполнении этого значения (элементы должны существовать), и если вы измените их будет refire. Единственное, что я не знаю сейчас, это то, что происходит, когда вы стреляете в flexslider дважды ...

+0

Yea .. Я представил себе, что мой звонок происходил до того, как ng-repeat смог закончить загрузку всего. Я поместил свой javascript и код в директиву, потому что я провел довольно много исследований, и похоже, что лучше отказаться от такого рода вещей из контроллера. Я не уверен. Я получил его для работы с $ timeout, сегодня вечером я попробую ваше решение с этим сервисом $ watch, с которым я еще не знаком, и я вернусь к вам. –

+0

Я только что проверил его. В моем текущем состоянии это не сработает. Что касается моих исследований на $ watch, он будет продолжать искать изменения в отзывах, а затем запускает setupFlexslider(). Так как переменная моих отзывов по-прежнему жестко запрограммирована, изменений не производится, поэтому часы не работают. Вероятно, он будет работать, когда я загружу данные отзывов с сервера в будущем. Однако, по крайней мере на данный момент, $ timeout - это путь. BTW, я подтвердил, вы должны оставить все манипуляции с DOM вне контроллера, поэтому директива касается этого. –

+0

Я понимаю логику перемещения DOM из контроллера, но я слишком часто думаю, что в Angular люди создают бесполезные директивы. Что делать, если вы хотите использовать flexslider для изображений, видео или что-то еще? С директивным подходом вы получаете 3 директивы для одного и того же базового вызова. Я собираюсь развернуть скрипку и поиграть с этим. –