我正在尝试实现Angular UI Bootstrap轮播,但我正在使用它进行测验。因此,我不需要普通的Prev()和Next()按钮。
相反,我需要一个自定义的Next()按钮,确保他们在继续下一个问题/答案的“幻灯片”之前选择了答案。
如何挂钩carousel指令函数来运行我的代码然后使用carousel.next()函数?
谢谢, 斯科特
答案 0 :(得分:4)
没有正式的可能性来实现这一目标。但如果你愿意,这可以被黑客入侵。但我认为最好抓住引导原始的一个,看看角度引导ui源(carousel)并编写自己的包装器。
黑客攻击:
我们必须解决的第一个问题是,如何访问CarouselController
。没有公开此API的API,carousel
指令创建了一个独立的范围。要获得对此范围的访问权,在指令被angular实例化之后,需要表示轮播的元素。为了达到这个目的,我们可以使用像这样的指令,它必须放在与ng-controller相同的元素上:
app.directive('carouselControllerProvider', function($timeout){
return {
link:function(scope, elem, attr){
$timeout(function(){
var carousel = elem.find('div')[1];
var carouselCtrl = angular.element(carousel).isolateScope();
var origNext = carouselCtrl.next;
carouselCtrl.next = function(){
if(elem.scope().interceptNext()){
origNext();
}
};
});
}
};
});
我们必须在$timeout
调用中包装我们的代码,等待angular创建隔离范围(这是我们的第一次黑客攻击 - 如果我们不想要这个,我们必须将我们的指令放在旋转木马下。但这是不可能的,因为内容将被替换)。下一步是在更换后找到旋转木马的元素。通过使用函数isolateScope
,我们可以访问隔离的范围 - 例如到CarouselController
。
下一个黑客是,我们必须用我们的实现替换CarouselController
的原始下一个函数。但是为了稍后调用原始函数,我们必须保留此函数以供以后使用。现在我们可以替换next
函数。在这种情况下,我们调用自己的控制器的函数interceptNext
。我们可以通过代表我们控制器的元素的范围来访问这个函数。如果interceptNext
返回true
,我们会调用轮播的原始下一个功能。当然,您可以将完整的原始下一个功能暴露给我们的控制器 - 但为了演示目的,这已足够。我们定义我们的interceptNext
函数:
$scope.intercept = false;
$scope.interceptNext = function(){
console.log('intercept next');
return !$scope.intercept;
}
我们现在可以通过一个绑定到next
的复选框来控制轮播的$scope.intercept
功能。 PLUNKR证明了这一点。
我知道这不完全是你想要的,但是你如何能够做到这一点。
答案 1 :(得分:1)
那个黑客是整洁的迈克尔,我开始为我的需要做类似的事情。但后来才意识到我最终还是应该为开源社区做出贡献。
我刚刚提交了一个拉取请求来更新库,因此当前幻灯片的索引会暴露给Carousel范围。
https://github.com/angular-ui/bootstrap/pull/2089
此更改允许您在轮播模板中使用每个幻灯片行为。
此更改允许我覆盖基本轮播模板,以便例如在第一张幻灯片上“prev”按钮不显示或“next”按钮不会显示最终幻灯片。
您可以为自己的个人需求添加更复杂的逻辑,但以这种方式将当前索引暴露给$ scope是使框架的这一部分更加灵活的一部分。
修改强>
我为个人使用做了更多更改,但不想提供更接近您所需要的更改。
我修改了carousel指令,将“finish”属性添加到范围。
.directive('carousel', [function () {
return {
restrict: 'EA',
transclude: true,
replace: true,
controller: 'CarouselController',
require: 'carousel',
templateUrl: 'template/carousel/carousel.html',
scope: {
interval: '=',
noTransition: '=',
noPause: '=',
finish: '='
}
};
}])
然后,当我声明轮播时,我可以将方法传递给该指令属性,该属性是包含轮播的控制器范围内的方法。
<carousel interval="-1" finish="onFinish">
...
</carousel>
这允许我修改我的模板,使其具有如下所示的按钮:
<button ng-hide="slides().length-1 != currentIndex" ng-click="finish()" class="btn next-btn">finish<span class="glyphicon glyphicon-stats"></span></button>
因此它仅在正确的幻灯片上有条件地显示并且通过ng-click它调用carousel的$ scope.finish(),这是指向我为此应用程序创建的控制器中的方法的指针。
有意义吗?
编辑:仅当您不对ng-repeat使用排序功能时才有效。有一个错误会破坏幻灯片的索引以实现此类功能。