Изменение индекса AngularJS MD-вкладки не имеют никакого эффекта вообще

В моем приложении Angular у меня есть md-tabs, директива md-selected привязана к свойству в моем контроллере. Я хотел бы изменить текущую вкладку на ту, чей индекс задан функцией, называемой ng-click в другом месте в моем шаблоне.

Я сделал это следующим образом:

<div ng-controller="TrackingCtrl" layout-fill>
   <md-content ng-if="isSmart" layout-fill>
      <md-tabs md-selected="selectedIndex" layout-fill>
         <md-tab>.........</md-tab>
         <md-tab>.........</md-tab>
         <md-tab>.........</md-tab>
         <md-tab>
            <md-tab-label>{{ 'tracking.positions.TITLE' | translate }}</md-tab-label>
            <md-tab-body>
                <md-tab-content layout-fill flex>
                    <button ng-click="map.panTo(getPosition());displayMap();"></button>
            </md-tab-body>
         </md-tab>
    </md-tabs>
 </md-content>
</div>

В моем контроллере я:

  $scope.selectedIndex = 0;
  $scope.displayMap = function() {
      $scope.selectedIndex = 1;
  };

Но это не имеет никакого эффекта, когда я нажимаю кнопку, вызывающую displayMap();

Я проверил проблему:

  • Когда я устанавливаю $scope.selectedIndex = 1; в моем контроллере вкладка по умолчанию - та, которая имеет индекс 1. OK
  • Когда я устанавливаю md-selected = "1" в моем шаблоне, вкладка по умолчанию - та, которая имеет индекс 1. OK
  • Когда я устанавливаю точку останова в своем коде, и когда я нажимаю на свою кнопку, вызывается displayMap() и $scope.selectedIndex = 1; выполняется. OK

Кажется, все работает отлично... кроме того, что вкладка не изменяется.

Я запускаю Angular Материал 1.0.2

Я даже использовал $apply для принудительного обновления (без эффекта):

  $scope.selectedIndex = 0;
  $scope.displayMap = function () {
      $timeout(function () {
          if (!$scope.$$phase) {
              $scope.$apply(function () {
                  $scope.selectedIndex = 1;
              });
          }
      });
  };

Ответ 1

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

var self = this;
self.selectedIndex = 0;
self.displayMap = function (){
   self.selectedIndex = 1;
};

и моя разметка:

<div ng-controller="TrackingCtrl as tracking" layout-fill>
  <md-content ng-if="tracking.isSmart" layout-fill>
    <md-tabs md-selected="tracking.selectedIndex" layout-fill>
       <md-tab>.........</md-tab>
       <md-tab>.........</md-tab>
       <md-tab>.........</md-tab>
       <md-tab>
          <md-tab-label>{{ 'tracking.positions.TITLE' | translate }}</md-tab-label>
          <md-tab-body>
             <md-tab-content layout-fill flex>
                <button ng-click="tracking.displayMap();"></button>
             </md-tab-content>
          </md-tab-body>
       </md-tab>
  </md-tabs>
 </md-content>
</div>

Теперь работает отлично. Я предполагаю, что мой ng-if изменил мою область действия или так.

Ответ 2

Я рад, что вы нашли обходной путь для своей проблемы. Чтобы избежать этого поведения изначально, вы должны, вероятно, взглянуть на это обсуждение fooobar.com/questions/86505/....

Так как ваша переменная selectedIndex содержит примитив, каждая новая область применения - вы уже упоминали, что ngIf - уничтожает привязку данных и изменения в пределах дочернего объекта не будут влиять на "внешний".

В вашем случае просто используйте...

$scope.vm = {
  selectedIndex: 0
};

... следовать правилу точки.

Ответ 3

Возможно, я неправильно понял что-то о вашем вопросе, но это должно сработать...

Я создал плункер, и я не могу воспроизвести ваше поведение, он просто отлично работает.

Просмотр:

<md-tabs class="md-accent" md-selected="selectedIndex">
  <md-tab id="tab1">
    <md-tab-label>Item One</md-tab-label>
    <md-tab-body>
      data.selectedIndex = 0;
    </md-tab-body>
  </md-tab>      
  <md-tab id="tab3">
    <md-tab-label>Item Two</md-tab-label>
    <md-tab-body>
      data.selectedIndex = 1;
    </md-tab-body>
  </md-tab>
</md-tabs>

<md-button ng-click="displayMap()">Map</md-button>

контроллер

  function AppCtrl ( $scope ) {
    $scope.selectedIndex = 0;

    $scope.displayMap = function() {
      $scope.selectedIndex = 1; 
  };

Не могли бы вы проверить его? Надеюсь, что это поможет.

Plunker здесь

Ответ 4

вот мое решение:

<div layout="column" flex>
            <md-tabs md-dynamic-height md-border-bottom md-selected="vm.selectedIndex">
                <md-tab label="Genel" md-on-select="vm.selectedIndex = 0">
                  <div class="md-padding">{{vm.selectedIndex}}</div>
                </md-tab>
                <md-tab label="Sipariş / Planlama" md-on-select="vm.selectedIndex = 1">
                  <div class="md-padding">{{vm.selectedIndex}}</div>
                </md-tab>
                <md-tab label="Kalite Kontrol Oranları" md-on-select="vm.selectedIndex = 2">
                  <div class="md-padding">{{vm.selectedIndex}}</div>
                </md-tab>
                <md-tab label="E-Posta" md-on-select="vm.selectedIndex = 3">
                  <div class="md-padding">{{vm.selectedIndex}}</div>
                </md-tab>
            </md-tabs>
        </div>

Ответ 5

С помощью md-selected = 0 вы переходите к первой вкладке. И md-selected = 1 ко второй вкладке.

кнопка:

<md-button ng-click="displayMap()">Map</md-button> 

контроллер:

 $scope.displayMap = function() {
      $scope.selectedIndex = 1; //select second tab
  };