twitter-bootstrap 你如何绑定到 Angular-UI 的 Carousel Slide Events?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24686119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you Bind to Angular-UI's Carousel Slide Events?
提问by jduprey
I'm using Angular-UI's carousel and I need to tell my google charts to redraw after they have slid into view. In spite of what I've read, I can't seem to hook into the event.
我正在使用 Angular-UI 的轮播,我需要告诉我的谷歌图表在它们滑入视图后重新绘制。不管我读过什么,我似乎都无法融入这个事件。
See my attempt: http://plnkr.co/edit/Dt0wdzeimBcDlOONRiJJ?p=preview
查看我的尝试:http: //plnkr.co/edit/Dt0wdzeimBcDlOONRiJJ?p=preview
HTML:
HTML:
<carousel id="myC" interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
On document load:
在文档加载时:
$('#myC').live('slid.bs.carousel', function (event) { console.log("slid"); } );
It should work something like this: http://jsfiddle.net/9fwuq/- non-angular-ui carousel
它应该像这样工作:http: //jsfiddle.net/9fwuq/- non-angular-ui carousel
Perhaps there is a more Angular way to hook into the fact that my chart has slid into view?
也许有一种更 Angular 的方式来了解我的图表已经滑入视图的事实?
回答by runTarm
There are 3 ways I can think of and that depends of your requirement.
我可以想到 3 种方法,这取决于您的要求。
Please see http://plnkr.co/edit/FnI8ZX4UQYS9mDUlrf6o?p=previewfor examples.
有关示例,请参阅http://plnkr.co/edit/FnI8ZX4UQYS9mDUlrf6o?p=preview。
use $scope.$watch for an individual slide to check if it is become active.
$scope.$watch('slides[0].active', function (active) { if (active) { console.log('slide 0 is active'); } });use $scope.$watch with custom function to find an active slide.
$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 a custom directive to intercept select() function of the carousel directive.
.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); }; } }; });and use it like this:
$scope.onSlideChanged = function (nextSlide, direction) { console.log('onSlideChanged:', direction, nextSlide); };and in html template:
<carousel interval="myInterval" on-carousel-change="onSlideChanged(nextSlide, direction)"> ...
对单个幻灯片使用 $scope.$watch 以检查它是否处于活动状态。
$scope.$watch('slides[0].active', function (active) { if (active) { console.log('slide 0 is active'); } });使用带有自定义函数的 $scope.$watch 来查找活动幻灯片。
$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); } });使用自定义指令拦截轮播指令的 select() 函数。
.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); }; } }; });并像这样使用它:
$scope.onSlideChanged = function (nextSlide, direction) { console.log('onSlideChanged:', direction, nextSlide); };并在 html 模板中:
<carousel interval="myInterval" on-carousel-change="onSlideChanged(nextSlide, direction)"> ...
Hope this help : )
希望这有帮助:)
回答by Manish Kumar
AngularUI Bootstrap has changed naming conventions for controllers as thery have prefixed all of their controllers with prefix uib, so below is the updated solution of the original solution provided by runTarm:
AngularUI Bootstrap 已经更改了控制器的命名约定,因为它们已为所有控制器添加了 prefix 前缀uib,因此以下是由 提供的原始解决方案的更新解决方案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 with TypeScript:
带有 TypeScript 的 Angular:
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;
}
}
}
Thanks,
谢谢,
回答by Lu Chinke
Following the answer given by runTarm If you want to know the index of the next slide, you should add something like this:
按照runTarm给出的答案,如果你想知道下一张幻灯片的索引,你应该添加如下内容:
.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);
};
}
};
})
Then, in the controller you just need to do this to catch the new index:
然后,在控制器中,您只需要执行此操作即可捕获新索引:
$scope.onSlideChanged = function (nextSlide, direction, nextIndex) {
console.log(nextIndex);
}
回答by R. Kazeno
I managed to modify runTarm's answer so that it calls the callback once the slide has finished sliding into view (i.e. the sliding animation has finished). Here's my code:
我设法修改了 runTarm 的答案,以便它在幻灯片完成滑入视图后调用回调(即滑动动画已完成)。这是我的代码:
.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);
};
}
};
});
The secret lies in using $animate's event handler to call our function once the animation is finished.
秘诀在于使用 $animate 的事件处理程序在动画完成后调用我们的函数。
回答by ionous
here's an alternate method that uses controllers, somewhere between runTarm's #2 and #3.
这是一种使用控制器的替代方法,介于 runTarm 的 #2 和 #3 之间。
original HTML + a new div:
原始 HTML + 一个新的 div:
<carousel id="myC" interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<div ng-controller="SlideController"> <!-- NEW DIV -->
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</div>
</slide>
</carousel>
the custom controller:
自定义控制器:
.controller('SlideController',
function($log, $scope) {
var slide = $scope.slide;
$scope.$watch('slide.active', function(newValue) {
if (newValue) {
$log.info("ACTIVE", slide.id);
}
});
});
回答by racitup
And if you just want to start playing a video when the slide comes into view, and pause when it leaves:
如果您只想在幻灯片进入视图时开始播放视频,并在幻灯片离开时暂停:
JS
JS
{# Uses angular v1.3.20 & angular-ui-bootstrap v0.13.4 Carousel #}
{% addtoblock "js" %}<script type="text/javascript">
angular.module('videoplay', []).directive('videoAutoCtrl', function() {
return {
require: '^carousel',
link: function(scope, element, attrs) {
var video = element[0];
function setstate(visible) {
if(visible) {
video.play();
} else {
video.pause();
}
}
// Because $watch calls $parse on the 1st arg, the property doesn't need to exist on first load
scope.$parent.$watch('active', setstate);
}
};
});
</script>{% endaddtoblock %}
{% addtoblock "ng-requires" %}videoplay{% endaddtoblock %}
NOTE: Has additional bits for Django
注意:Django 有额外的位
HTML:
HTML:
<carousel interval="15000">
<slide>
<video class="img-responsive-upscale" video-auto-ctrl loop preload="metadata">
<source src=
...

