Какой хороший способ управлять программным обеспечением angular -ui accordion? - программирование
Подтвердить что ты не робот

Какой хороший способ управлять программным обеспечением angular -ui accordion?

Я использую директиву гармонии от http://angular-ui.github.com/bootstrap/, и мне нужно больше контролировать, когда аккордеоны открываются и закрываются.

Чтобы быть более точным, мне нужна кнопка внутри группы аккордеона, которая закроет его родительский аккордеон и откроет следующий (так что в основном имитирует, что щелчок следующего заголовка будет делать, если close-others был установлен в true). Я также должен выполнить некоторую проверку, прежде чем я смогу разрешить закрытие аккордеона, и следующий, который нужно открыть, и мне также нужно подключить это событие для кликов на заголовках аккордеона.

Я новичок в angular, и мы в настоящее время переписываем приложение из Backbone + JQuery на Angular. В Backbone-версии мы использовали Twitter-бутстрап-аккордеоны, и мы открывали и закрывали их с помощью JQuery. Хотя мы все еще можем это делать, я бы скорее избавился от манипуляций JQuery DOM, поэтому я ищу для этого чистое решение angular.

То, что я пытался сделать с точки зрения проверки,

<accordion-group ng-click="close($event)">

и в моем контроллере

    event.preventDefault();
    event.stopPropagation();

Это явно не работает, поскольку элемент DOM заменяется директивой, и обработчик кликов никогда не добавляется. Я перебираю исходный код (и нашел несколько очень приятных недокументированных функций), но я в недоумении, где даже начать решение этой конкретной задачи. Я рассматривал forking angular -ui и попытался добавить эту функциональность в директиву гармоник, но если я смогу добиться этого, не изменяя директивы, которая будет намного приятнее.

4b9b3361

Ответ 1

В accordion-group есть атрибут is-open, который указывает на связующее выражение. Используя это выражение, вы можете программно управлять элементами аккордеона, например:

<div ng-controller="AccordionDemoCtrl">
  <accordion>
    <accordion-group ng-repeat="group in groups" heading="{{group.title}}" is-open="group.open">
      {{group.content}}
    </accordion-group>    
  </accordion>
  <button class="btn" ng-click="groups[0].open = !groups[0].open">Toggle first open</button>
  <button class="btn" ng-click="groups[1].open = !groups[1].open">Toggle second open</button>
</div>

и рабочий фрагмент здесь: http://plnkr.co/edit/DepnVH?p=preview

Ответ 2

Для тех, у кого решение @pkozlowski.opensource не работает (например, я), вы можете просто заставить компонент принять CSS, который закроет его (без перехода).

Теория: Директива angular расширяется в стандартные HTML-элементы div, в основном, где стили CSS придают ей внешний вид аккордеона. Div с классом .panel-collapse является телом элемента аккордеонной группы. Вы можете поменять свой второй класс с .in на .collapse вместе с несколькими другими изменениями, как показано ниже.

Код:

$scope.toggleOpen = function(project) {

        var id = '<The ID of the accordion-group you want to close>';
        var elements = angular.element($document[0].querySelector('#'+id));
        var children = elements.children();

        for(var i = 0; i < children.length; i++) {

            var child = angular.element(children[i]);

            if(child.hasClass('panel-collapse')) {
                if(child.hasClass('in')) { // it is open
                    child.removeClass('in');
                    child.addClass('collapse');
                    child.css('height', '0px');
                } else { // it is closed
                    child.addClass('in');
                    child.removeClass('collapse');
                    child.css('height', 'auto');
                }

            }
        }
    };

Как мы говорим о Angular, очень возможно, что вы генерируете аккордеон через тег ng-repeat. В этом случае вы также можете сгенерировать идентификатор для таких элементов, как:

<accordion-group ng-repeat="user in users"
                 is-disabled="user.projects.length == 0"
                 id="USER{{user._id}}">

Учитывая пользовательскую модель Mongoose, обратите внимание, что идентификатор, который я даю, не user._id, а перед ним добавлен USER. Это связано с тем, что Mongoose может генерировать идентификатор, который начинается численно, а querySelector не нравится;-) go figure!