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:
Slide {{$index}}
{{slide.text}}
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.
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'); } });
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); } });
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:
Slide {{$index}}
{{slide.text}}
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: