Como você se vincular a events de slides de carrossel do Angular-UI?

Estou usando o carrossel do Angular-UI e preciso dizer aos meus charts do google para redesenhar depois que eles aparecerem. Apesar do que eu li, não consigo me conectar ao evento.

Veja minha tentativa: http://plnkr.co/edit/Dt0wdzeimBcDlOONRiJJ?p=preview

HTML:

      

Na carga do documento:

 $('#myC').live('slid.bs.carousel', function (event) { console.log("slid"); } ); 

Deve funcionar algo assim: http://jsfiddle.net/9fwuq/ – carrossel não-angular-ui

Talvez haja uma maneira mais angular de me ligar ao fato de que meu gráfico apareceu?

Existem 3 maneiras que eu posso pensar e isso depende de sua exigência.

Consulte http://plnkr.co/edit/FnI8ZX4UQYS9mDUlrf6o?p=preview para ver exemplos.

  1. use $ scope. $ observe um slide individual para verificar se ele está ativo.

     $scope.$watch('slides[0].active', function (active) { if (active) { console.log('slide 0 is active'); } }); 
  2. use $ scope. $ watch com function personalizada para encontrar um slide ativo.

     $scope.$watch(function () { for (var i = 0; i < slides.length; i++) { if (slides[i].active) { return slides[i]; } } }, function (currentSlide, previousSlide) { if (currentSlide !== previousSlide) { console.log('currentSlide:', currentSlide); } }); 
  3. use uma diretiva personalizada para interceptar a function select () da diretiva carrossel.

     .directive('onCarouselChange', function ($parse) { return { require: 'carousel', link: function (scope, element, attrs, carouselCtrl) { var fn = $parse(attrs.onCarouselChange); var origSelect = carouselCtrl.select; carouselCtrl.select = function (nextSlide, direction) { if (nextSlide !== this.currentSlide) { fn(scope, { nextSlide: nextSlide, direction: direction, }); } return origSelect.apply(this, arguments); }; } }; }); 

    e usá-lo assim:

     $scope.onSlideChanged = function (nextSlide, direction) { console.log('onSlideChanged:', direction, nextSlide); }; 

    e no template html:

      ... 

Espero que esta ajuda 🙂

O AngularUI Bootstrap mudou as convenções de nomenclatura dos controladores, pois eles prefixaram todos os seus controladores com o prefixo uib , portanto, abaixo está a solução atualizada da solução original fornecida pelo runTarm :

Angular:

 .directive('onCarouselChange', function($parse) { return { require: '^uibCarousel', link: function(scope, element, attrs, carouselCtrl) { var fn = $parse(attrs.onCarouselChange); var origSelect = carouselCtrl.select; carouselCtrl.select = function(nextSlide, direction, nextIndex) { if (nextSlide !== this.currentSlide) { fn(scope, { nextSlide: nextSlide, direction: direction, nextIndex: this.indexOfSlide(nextSlide) }); } return origSelect.apply(this, arguments); }; } }; }); 

Angular com TypeScript:

 module App.Directive { export class CarouselChange implements ng.IDirective { public require: string = '^uibCarousel'; constructor(private $parse: ng.IParseService) { } public link: ng.IDirectiveLinkFn = (scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: any, carouselCtrl: any) => { var fn = this.$parse(attributes.carouselChange); var origSelect = carouselCtrl.select; carouselCtrl.select = function(nextSlide, direction) { if (nextSlide !== this.currentSlide) { fn(scope, { nextSlide: nextSlide, direction: direction }); } return origSelect.apply(this, arguments); }; } static Factory(): ng.IDirectiveFactory { var directive: ng.IDirectiveFactory = ($parse: ng.IParseService) => new CarouselChange($parse); directive['$inject'] = ["$parse"]; return directive; } } } 

Obrigado,

Seguindo a resposta dada por runTarm Se você quiser saber o índice do próximo slide, você deve adicionar algo assim:

  .directive('onCarouselChange', function ($parse) { return { require: 'carousel', link: function (scope, element, attrs, carouselCtrl) { var fn = $parse(attrs.onCarouselChange); var origSelect = carouselCtrl.select; carouselCtrl.select = function (nextSlide, direction,nextIndex) { if (nextSlide !== this.currentSlide) { fn(scope, { nextSlide: nextSlide, direction: direction, nextIndex:this.indexOfSlide(nextSlide) }); } return origSelect.apply(this, arguments); }; } }; }) 

Então, no controlador você só precisa fazer isso para pegar o novo índice:

 $scope.onSlideChanged = function (nextSlide, direction, nextIndex) { console.log(nextIndex); } 

Consegui modificar a resposta da runTarm para que ela chamasse o retorno de chamada assim que o slide terminasse de aparecer (ou seja, a animação deslizante foi concluída). Aqui está meu código:

 .directive('onCarouselChange', function ($animate, $parse) { return { require: 'carousel', link: function (scope, element, attrs, carouselCtrl) { var fn = $parse(attrs.onCarouselChange); var origSelect = carouselCtrl.select; carouselCtrl.select = function (nextSlide, direction) { if (nextSlide !== this.currentSlide) { $animate.on('addClass', nextSlide.$element, function (elem, phase) { if (phase === 'close') { fn(scope, { nextSlide: nextSlide, direction: direction, }); $animate.off('addClass', elem); } }); } return origSelect.apply(this, arguments); }; } }; }); 

O segredo está em usar o manipulador de events do $ animate para chamar nossa function assim que a animação terminar.

aqui está um método alternativo que usa controladores, em algum lugar entre os # 2 e # 3 do runTarm.

HTML original + um novo div:

   

o controlador personalizado:

  .controller('SlideController', function($log, $scope) { var slide = $scope.slide; $scope.$watch('slide.active', function(newValue) { if (newValue) { $log.info("ACTIVE", slide.id); } }); }); 

E se você quiser apenas começar a reproduzir um vídeo quando o slide aparecer, e pause quando ele sair:

JS

 {# Uses angular v1.3.20 & angular-ui-bootstrap v0.13.4 Carousel #} {% addtoblock "js" %}{% endaddtoblock %} {% addtoblock "ng-requires" %}videoplay{% endaddtoblock %} 

NOTA: Tem bits adicionais para o Django

HTML: