admin管理员组

文章数量:1193969

In my Angular app, I have a md-tabs whose md-selected directive is binded to a property in my controller. I'd like to change the current tab to the one whose index is set by a function called by ng-click somewhere else in my template.

I did it this way:

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

In my controller I have :

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

But it has no effect at all when I click my button which calls displayMap();

I've inspected the problem:

  • When I set $scope.selectedIndex = 1; in my controller, the default tab is the one whose index is 1. OK
  • When I set md-selected="1" in my template, the default tab is the one whose index is 1. OK
  • When I set a breakpoint in my code, and when I click my button, displayMap() is called, and $scope.selectedIndex = 1; is executed. OK

It seems everything works fine... except the tab doesn't change.

I'm running Angular Material 1.0.2

I even used $apply to force update (no effect) :

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

In my Angular app, I have a md-tabs whose md-selected directive is binded to a property in my controller. I'd like to change the current tab to the one whose index is set by a function called by ng-click somewhere else in my template.

I did it this way:

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

In my controller I have :

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

But it has no effect at all when I click my button which calls displayMap();

I've inspected the problem:

  • When I set $scope.selectedIndex = 1; in my controller, the default tab is the one whose index is 1. OK
  • When I set md-selected="1" in my template, the default tab is the one whose index is 1. OK
  • When I set a breakpoint in my code, and when I click my button, displayMap() is called, and $scope.selectedIndex = 1; is executed. OK

It seems everything works fine... except the tab doesn't change.

I'm running Angular Material 1.0.2

I even used $apply to force update (no effect) :

  $scope.selectedIndex = 0;
  $scope.displayMap = function () {
      $timeout(function () {
          if (!$scope.$$phase) {
              $scope.$apply(function () {
                  $scope.selectedIndex = 1;
              });
          }
      });
  };
Share Improve this question edited Dec 17, 2018 at 9:43 Arman Fatahi 2,9953 gold badges27 silver badges38 bronze badges asked Jan 21, 2016 at 23:10 user4856537user4856537 3
  • 1 FYI - $timeout by itself will trigger $apply internally . Doesn't answer question ... just passing on info – charlietfl Commented Jan 22, 2016 at 0:12
  • Suggest check in angular-material github issue tracker also. Lots of tabs issues there – charlietfl Commented Jan 22, 2016 at 0:13
  • Yes I will check this out – user4856537 Commented Jan 22, 2016 at 7:20
Add a comment  | 

5 Answers 5

Reset to default 10

I'm glad you've found a workaround for your issue. To avoid that behaviour initially, you should probably have a look at this stackoverflow discussion.

Since your selectedIndex variable holds a primitive, every new Scope introduced - you already mentioned the ngIf - destroys the data binding and changes within the child scope will not have effect on the 'outside'.

In your case, just use...

$scope.vm = {
  selectedIndex: 0
};

...to follow the dot rule.

I solved my problem which was certainly caused by a scope issue. I simply used the controller as syntax, and declared every previous scope data with:

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

and my markup:

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

Works perfect now. I guess my ng-if was modifying my scope or so.

Maybe I've misunderstood something about your question but this should work...

I've created a plunker and I cannot reproduce your behaviour, it's just working fine.

View:

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

Controller:

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

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

Could you please check it? Hope it helps

Plunker here

here is my solution:

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

With md-selected = 0 you go to the first tab. And md-selected = 1 to the second tab.

button:

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

controller:

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

本文标签: javascriptChange index of AngularJS mdtabs have no effect at allStack Overflow