Странное поведение коллапса angular bootstrap

Столкнулся со странным поведением uib-collapse. Предположим, у меня есть список элементов, и я хочу, чтобы каждый из них был свернут. Также я хочу периодически обновлять его содержимое в зависимости от чего-то.

Например: у меня есть несколько элементов, и у каждого из них есть описание, состоящее из нескольких разделов. Я могу выбрать элемент, и разделы описания должны быть заполнены содержимым описания элемента. Проблема в том, что каждый раз, когда я обновляю его содержимое, некоторые разделы сворачиваются (несмотря на то, что я установил для uib-collapse значение false)

Мой контроллер:

var i = 0;
$scope.sections = [0,1,2];
$scope.next = function(nextOffset) {
    i+=nextOffset;
    $scope.sections = [i, i+1, i+2]
}

Мой шаблон:

<button ng-click="next(1)" style="margin-bottom: 10px">Next item</button>
<button ng-click="next(2)" style="margin-bottom: 10px">Next next item</button>
<button ng-click="next(3)" style="margin-bottom: 10px">Next next next item</button>

<div ng-repeat="section in sections">
  <div uib-collapse="false">
    <div class="well well-lg">{{ section }}</div>
  </div>
</div>

Поэтому, когда я нажимаю первую кнопку, происходит переход только в одном разделе. Когда я нажимаю второй, 2 раздела выполняют переход, а нажатие на третью кнопку приводит к переходу всего раздела.

См. plunkr

Любые идеи?

UPD: если $scope.sections массив объектов, а не примитивов, то все секции имеют переход в каждом из 3-х случаев. Это так некрасиво...


person Boris Parnikel    schedule 12.11.2015    source источник
comment
Я не могу воспроизвести вашу ошибку на вашем plunkr   -  person IggY    schedule 12.11.2015
comment
Ошибок нет. Странно, что коллапс/расширение вызывается иногда несмотря на то, что uib-collapse постоянно false   -  person Boris Parnikel    schedule 12.11.2015


Ответы (2)


Вы не обновляете существующий контент, вы каждый раз добавляете новые массивы, что заставит ng-repeat удалить старые элементы DOM и вставить новые.

Если вы попробуете с track by $index, вы увидите разницу:

<div ng-repeat="section in primitiveSections track by $index">

Демо: http://plnkr.co/edit/hTsVBrRLa8nWXhaqfhVK?p=preview

Обратите внимание, что track by $index может быть не тем решением, которое вам нужно в вашем реальном приложении, я просто использовал его в демонстрационных целях.

Что вам, вероятно, нужно, так это просто изменить существующие объекты в массиве.

Например:

$scope.nextObject = function(nextOffset) {

  j += nextOffset;

  $scope.objectSections.forEach(function (o, i) {
    o.content = j + i;
  });
};

Демо: http://plnkr.co/edit/STxy1lAUGnyxmKL7jYJH?p=preview


Обновлять

Из исходного кода коллапса:

scope.$watch(attrs.uibCollapse, function(shouldCollapse) {
  if (shouldCollapse) {
    collapse();
  } else {
    expand();
  }
});

Когда добавляется новый элемент, прослушиватель часов будет выполняться, shouldCollapse всегда будет ложным в вашем случае, поэтому он выполнит функцию expand.

Функция expand всегда будет выполнять анимацию:

function expand() {
  element.removeClass('collapse')
    .addClass('collapsing')
    .attr('aria-expanded', true)
    .attr('aria-hidden', false);

  if ($animateCss) {
    $animateCss(element, {
      addClass: 'in',
      easing: 'ease',
      to: {
        height: element[0].scrollHeight + 'px'
      }
    }).start().finally(expandDone);
  } else {
    $animate.addClass(element, 'in', {
      to: {
        height: element[0].scrollHeight + 'px'
      }
    }).then(expandDone);
  }
}

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

person tasseKATT    schedule 12.11.2015
comment
Спасибо за ответ, вы правы! Но почему он вообще анимируется, если я выбираю разные объекты? См. plunkr: plnkr.co/edit/rP1AlbLsi1qXuJOJL0D6?p=preview. Насколько я понимаю, он работает с механизмом scope.$watch для атрибута uib-collapse, но не меняется! - person Boris Parnikel; 12.11.2015
comment
Не за что :) Мне нужно взглянуть на исходный код angular-ui, чтобы узнать, предназначен он или нет. Я обновлю, если найду что-нибудь. - person tasseKATT; 12.11.2015
comment
@CodeMed Я вижу, что кто-то уже ответил на ваш вопрос. Дайте мне знать, если ответ вам не поможет, и я посмотрю. - person tasseKATT; 06.04.2016
comment
@tasseKATT Большое спасибо. На самом деле мне удалось решить другую проблему, но я очень ценю вашу доступность. - person CodeMed; 07.04.2016
comment
@CodeMen Я посмотрю через некоторое время, когда у меня будет время :) - person tasseKATT; 07.04.2016

это комментарий к исходной библиотеке ui-bootstrap: (и новая директива с префиксом uib не соответствует этому комментарию.)

// ВАЖНО: Высота должна быть установлена ​​перед добавлением "сворачивающегося" класса. В противном случае браузер пытается анимировать от высоты 0 (в сворачивающемся классе) до заданной здесь высоты.

используйте устаревшую директиву "collapse" вместо новой "uib-collapse", пока она не будет исправлена.

person mehmetenes    schedule 11.12.2015