问题
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;
});
}
});
};
回答1:
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.
回答2:
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.
回答3:
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
回答4:
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>
回答5:
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
};
来源:https://stackoverflow.com/questions/34936155/change-index-of-angularjs-md-tabs-have-no-effect-at-all