2014-01-24 5 views
1

Я пытаюсь реализовать угловую карусели Bootstrap UI, но я использую ее для викторины. Поэтому мне не нужны обычные кнопки Prev() и Next().AngularJS - Захват в Угловой UT Bootstrap - Карусель Custom Next()?

Скорее, мне нужна пользовательская кнопка «Далее»(), которая гарантирует, что они выбрали ответ, прежде чем перейти к следующему «слайду» вопросов/ответов.

Как подключить функции карусели для запуска моего кода, а затем использовать функцию carousel.next()?

Спасибо, Скотт

ответ

4

Там нет официальной возможности для достижения этой цели. но это можно взломать, если хотите. Но я думаю, что лучше захватить исходный ботстрап, посмотрите на угловые бутстрапы ui sources (carousel) и напишите свою собственную обертку.

вот хак:

Первая проблема, которую мы должны решить в том, как получить доступ к CarouselController. API, который предоставляет это, отсутствует, а директива carousel создает изолированную область. Чтобы получить доступ к этой области, нужен элемент, представляющий карусель после того, как директива была создана с помощью углового. Для достижения этой цели мы можем использовать директиву, как этот, который должен быть помещен в том же элементе, как наши нг-контроллер:

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 вызова ждать, пока угловые не создали изолированные scope (это наш первый взлом - если мы этого не хотим, нам нужно было разместить нашу инструкцию под карусели, но это невозможно, потому что содержимое будет заменено). Следующий шаг - найти элемент для карусели после замены. Используя функцию isolateScope, мы имеем доступ к изолированной области - например. до CarouselController.

Следующий взлом - мы должны заменить исходную следующую функцию CarouselController нашей реализацией. Но для вызова исходной функции позже мы должны сохранить эту функцию для последующего использования. Теперь мы можем заменить функцию next. В этом случае мы вызываем функцию interceptNext нашего собственного контроллера. Мы можем получить доступ к этой функции через область элемента, представляющего наш контроллер. Если interceptNext возвращает true, мы вызываем оригинальную следующую функцию карусели. Конечно, вы можете выставить полную оригинальную следующую функцию нашему контроллеру, но для демонстрационных целей этого достаточно. И мы определяем нашу interceptNext функции следующим образом:

$scope.intercept = false; 
$scope.interceptNext = function(){ 
    console.log('intercept next'); 
    return !$scope.intercept; 
} 

Теперь мы можем контролировать next функции карусели с помощью флажка, который связан с $scope.intercept. A PLUNKR демонстрирует это.

Я знал, что это не совсем то, что вы хотите, но как вы можете это сделать.

+0

Отлично, спасибо! – Scott

+0

@michael Я пытаюсь добавить carouselCtrl.prev .... но добавление как next, так и prev не работает. Пожалуйста, предложите – anam

1

Этот хак опрятный майкл, я начал работать над чем-то похожим для своих нужд. Но потом я понял, что могу, наконец, окунуться в то, чтобы внести вклад в сообщество с открытым исходным кодом.

Я просто передал запрос на перенос, чтобы обновить библиотеку, чтобы индекс текущего слайда был открыт для области карусели.

https://github.com/angular-ui/bootstrap/pull/2089

Это изменение позволяет иметь за горкой поведение в шаблоне карусельного.

Это изменение позволило мне переопределить шаблон базовой карусели, чтобы, например, на первом слайде кнопка "prev" не показывалась или кнопка "next" не показывалась для последнего слайда.

Вы можете добавить более сложную логику для своих личных нужд, но разоблачение текущего индекса таким образом в области $ scope является частью большей гибкости этой части структуры.

EDIT

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

Я изменил директиву карусели, добавив свойство «закончить» в область видимости.

.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> 

Так это только показывает, условно на правильной горку и нг щелкни его вызовом карусели в $ scope.finish(), который является указателем на метод в контроллере, который я создал для этого приложения.

Имеют смысл?

Редактировать: Это работает, только если вы не используете функцию сортировки с ng-repeat. Существует ошибка, которая разбивает индексирование слайдов для такого рода функций.

+0

Не могли бы вы показать мне, как вы получаете доступ к переменной $ scope.currentIndex в шаблоне? Я сталкиваюсь с тем же вопросом и не могу понять. –

+0

У меня нет доступа к этому. Кнопка завершения находится вне карусели, а функция, связанная с ng-кликом, - это те же функции, которые связаны с параметром финиша, который я добавил в кареты, через контроллер внешней области. – Bon

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