2016-02-25 2 views
1

У меня проблема, с которой я не могу обойтись.Angular ngRepeat - Обновление после изменения HTML

У меня есть простая установка углового повторения для вывода некоторых слайдов. Существуют различные наборы слайдов, которые можно изменить. Я использую плагин jQuery для слайдера, который отлично работает.

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

У меня есть рабочий пример здесь:

http://jsfiddle.net/antony_publica/ccvjz4au/

Чтобы проверить, пролистывания слайдов, должно быть 1, 2 3, затем 4. Нажмите листинге 2. Теперь, когда вы прокручиваете вы видите слайды 1 до 8. Когда он должен иметь 5 по 8.

HTML

<div ng-controller="MyCtrl"> 
    Listing Id: {{current_listing.id}} 
    <div class="image_slider col-md-9" ng-if="current_listing"> 
    <div class="slide slick-slide" ng-repeat="slide in current_listing.slides" repeat-end="initSlider()" > 
     {{slide}} 
    </div> 
    </div> 
    <button ng-click="current_listing = listing">Listing 1</button> 
    <button ng-click="current_listing = listing2">Listing 2</button> 
</div> 

JS

var myApp = angular.module('myApp',[]); 

myApp.directive("repeatEnd", function(){ 
    return { 
    restrict: "A", 
    link: function (scope, element, attrs) { 
     if (scope.$last) { 
     setTimeout(function(){ 
      scope.$eval(attrs.repeatEnd); 
     }, 50); 
     } 
    } 
    }; 
}); 


function MyCtrl($scope) { 
    $scope.listing = { 
     id: 1, 
     slides: ['Slide 1','Slide 2','Slide 3', 'Slide 4'] 
    }; 
    $scope.listing2 = { 
     id: 2, 
     slides: ['Slide 5','Slide 6','Slide 7', 'Slide 8'] 
    }; 
    $scope.current_listing =$scope.listing; 
    $scope.initSlider = function(){ 
     if($('.image_slider').hasClass('slick-slider')){ 
     $('.image_slider').slick('unslick'); 
     } 
     $('.image_slider').slick(); 
    } 
} 

ответ

1

В вашей директиве я создал сценарий разбивки на страницы, в котором будут отображаться только слайды, которые содержатся в вашем значении свойства объекта current_listing.slides. Я удалил директиву ng-repeat из вашего html, потому что он добавлял еще четыре слайда в дом каждый раз, когда вы нажимали кнопку списка. Я также переместил ваш код {{ scope variable here }} из вашего html и разместил переменные внутри директив ng-bind, чтобы скобки не отображались на экране перед угловыми компиляторами. Я также добавил директиву ng-click к вашим кнопкам перечисления, которые передают целочисленное значение контроллеру, который устанавливает значение current_listing.

Живого пример: http://codepen.io/larryjoelane/pen/ZWzObo

HTML:

<div ng-app="myApp" ng-controller="MyCtrl"> 
    Listing Id: <span ng-bind="current_listing.id"></span> 

    <div repeat-end class="image_slider col-md-9"> 
    <div ng-bind="slides" class="slick"> 
    </div> 
    </div> 
    <button ng-click="changeListing(1)">Listing 1</button> 
    <button ng-click="changeListing(2)">Listing 2</button> 
</div> 

Угловой/JQuery:

(function($) { 

    var myApp = angular.module('myApp', []); 

    myApp.directive("repeatEnd", function($timeout) { 
    return { 
     restrict: "A", 
     link: function(scope, element, attrs) { //begin link 

      //let angular compile first then call the jquery code 
      $timeout(function() { //begin timeout 

      function buildSlides() { 

       //array to hold the slides 
       var slides = []; 

       //loop through and the opening and closing div tags to the slides 
       for (var i = 0; i < scope.current_listing.slides.length; i++) { //begin for 

       //add the slide 
       slides.push("<div>" + scope.current_listing.slides[i] + "</div>"); 

       } //end for 

       //return the slides html 
       return slides.join(""); 

      } //end function   

      //initalize slick slider 
      $(element).slick(scope.$eval()); 

      //check for changes in the listing 
      scope.$watch('current_listing', function(newValue, oldValue) { //begin watch 

       //if there is a new value 
       if (newValue) { 

       //destroy the slick slider 
       $(element).slick("unslick"); 

       //store the html 
       var content = buildSlides(); 

       //populate the slides 
       scope.slides = scope.$eval(element.html(content)); 

       //reinitalize slick slider 
       $(element).slick(); 

       } 
      }); //end watch 

      }); //end timeout 

     } //end link 

    }; 
    }); 

    myApp.controller("MyCtrl", ["$scope", "$timeout", function($scope, $timeout) { 

    $scope.listing = { 
     id: 1, 
     slides: ['Slide 1', 'Slide 2', 'Slide 3', 'Slide 4'] 
    }; 

    $scope.listing2 = { 
     id: 2, 
     slides: ['Slide 5', 'Slide 6', 'Slide 7', 'Slide 8'] 
    }; 

    //intialize the listing 
    $scope.current_listing = $scope.listing; 

    //change the listing on click 
    $scope.changeListing = function(listNum) { //begin function 

     //Assign the listings based on the listNum 
     //passed in as a parameter. 

     if (listNum === 1) { 
      $scope.current_listing = $scope.listing; 
     } else if (listNum === 2) { 
      $scope.current_listing = $scope.listing2; 
     } 

     } //end function 

    }]); 

})(jQuery); 
+0

Ах да, вот как мой фактический код контроллера настроен, я использовал пример с другой скрипки , Но на самом деле это не устраняет проблему. Пока вы меняете листинг, все еще остаются 8 слайдов. –

+0

@AntonyThompson Я собрал решение, которое должно работать так, как вы этого хотите. Проверьте мою ссылку для предварительного просмотра. Я обновлю свой ответ, чтобы отобразить его в прямом эфире всего за минуту. –

+0

Хорошее решение. Спасибо –

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