Вкладки Angular Bootstrap устанавливают активную вкладку с помощью разметки

Я пытаюсь сделать вкладку активной через разметку. По какой-то причине, когда я устанавливаю активный атрибут на вкладке, кажется, что состояние вкладок искажается. Страница загружается нормально, и вкладка, которая была установлена ​​как активная, будет деактивирована при нажатии на другую вкладку. Когда я снова нажимаю на тег, который был установлен с active = "true", ранее выбранная вкладка не будет снята с выбора.

...
<tab heading="Dynamic Title 1" active="true">Some Title 1</tab>
...

http://plnkr.co/edit/xzDbezXgkSMr6wokov6g?p=info

Я переключился на создание переменной, для которой установлено значение true при инициализации, и вставил ее в активный атрибут. Я надеюсь, что есть способ лучше.

  <tabset ng-init="startActive = true">
    ...
    <tab heading="Dynamic Title 1" active="startActive">Some Title 1</tab>
    ...
  </tabset>

http://plnkr.co/edit/mt5MQSZEl730fsMuMxg8

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


person Teeknow    schedule 03.12.2014    source источник


Ответы (2)


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

Постановка задачи

Использование вкладок UI Bootstrap, динамическое добавление вкладок на основе данных списка и поддержание активного состояния вне этих данных.

При использовании вкладок UI Bootstrap и создании таких вкладок:

<tab ng-repeat="item in page.data.list" active="item.active">

UI Bootstrap будет использовать привязку элемента для сохранения активного состояния. Если мы опустим активный атрибут, UI Bootstrap будет поддерживать его внутри, но тогда станет невозможно управлять активным состоянием извне, за исключением доступа к нему через один из следующих способов: $$ (какие неприкасаемые! )

Решение (Взлом)

Сохраните активное состояние в другом списке:

<div ng-controller="parasample-tabs">
{{activeState}}
<tabset ng-show="page.data.list.length">
    <tab ng-repeat="item in page.data.list" active="activeState[$index]">
                <tab-heading>
        <i style="cursor: pointer" class="glyphicon glyphicon-remove" ng-click="delTab($index)" prevent-default></i>
        Item {{$index +1}}
    </tab-heading>
    {{item.text}} - {{item.transcript}} - {{item.active}}
    </tab>
</tabset>
<!-- 
  For me this problem arose because I like to use self-contained, self-managing data 
  from factories, hence I call addItem not on a controller
-->
<button ng-click="page.addItem()">Add Item</button>
</div>

Теперь о контроллере, который окружает эти вкладки и управляет ими, а также их активным состоянием, а не записывает его в мои данные:

app.controller('parasample-tabs', function ($scope) {
    $scope.maxItems = 5;

    $scope.activeState = [];
    $scope.delTab = function (idx) {
        var list = $scope.page.data.list;
        if (list.length > 0) {
            $scope.page.delItem(idx);
            $scope.activeState.splice(idx, 1);
        }
    };
    $scope.$watch(
        "page.data.list.length",
        function (newLen, oldLen) {
            if (!newLen) return;
            // new item => new tab, make active
            if (newLen > oldLen)
                $scope.activeState.push("true");
        }
    );
});

Теперь UI Bootstrap получит доступ к массиву activeState и сохранит там активное состояние. В инициализации нет необходимости, так как об этом позаботятся.

Когда в наш список данных добавляется новый элемент, часы установят новую вкладку как активную (это я предпочитаю), а остальная часть списка будет обновлена ​​с помощью UI Bootstrap.

Однако при удалении нелегко определить, какой элемент был удален, поэтому мне пришлось заключить свой page.delItem в метод delTab контроллера.

Вот и скрипка, с которой можно поиграть.

Будем надеяться, что UI Bootstrap позволит другим способом поддерживать активное состояние вместо двусторонней привязки в активном атрибуте. Мне нравится иметь переменную «активный идентификатор».

Заявление об ограничении ответственности: мне известно, насколько это грязно, и я пока тестировал его только в Chrome, и он отлично работает.

person enpenax    schedule 20.03.2015

Вам здесь не хватает многих. Вот более расширяемый способ:

var app = angular.module('myApp',[]);

app.controller('MyController', ['$scope',function($scope){
  $scope.tab = 0;
  
  $scope.changeTab = function(newTab){
    $scope.tab = newTab;
  };
  
  $scope.isActiveTab = function(tab){
    return $scope.tab === tab;
  };
  
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE HTML>
<html ng-app="myApp">
	<head>
      <style type="text/css">
          .active{
          background-color:red;
        }
        </style>
	</head>
	
	<body ng-controller="MyController">
		<div>
			<div ng-class="{'active':isActiveTab(0)}" ng-click="changeTab(0)">Some Title 1</div>
			<div ng-class="{'active':isActiveTab(1)}" ng-click="changeTab(1)">Some Title 2</div>
		</div>
		<br/>
		<div ng-show="isActiveTab(0)">tab1</div>
		<div ng-show="isActiveTab(1)">tab2</div>

		
		<script type="text/javascript" src="js/angular-1.2.24.min.js"></script>
		<script type="text/javascript" src="js/app.js"></script>
		
	</body>
</html>

  1. Инициализация всегда должна происходить в контроллере.
  2. Измените значения с помощью функции контроллера. Здесь определяется как 'changeTab ()'
  3. Для проверки активных вкладок создайте функцию контроллера для сравнения, если текущее значение $ scope.tab равно текущей вкладке.

Я также добавил немного стиля, чтобы указать, какая вкладка активна.

person Immanuel Rosal    schedule 03.12.2014