Отдельный контроллер для каждой вкладки в angular -материале w/ui-router
Я пытаюсь реализовать мой md-tabs
, поэтому каждый md-tab
является отдельным состоянием с использованием angular -материала. Моя текущая разметка выглядит так:
md-tabs.is-flex.auto-flex(selected="selectedIndex",layout="vertical")
md-tab(on-select="selectTab(0)",label="Player",ui-sref="state1")
div.tab(ui-view)
md-tab(on-select="selectTab(1)",label="Map",ui-sref="state2")
div.tab(ui-view)
Я не думаю, что это допустимая разметка для ui-router. Возможно ли это сделать с текущей версией angular -материала и ui-router?
Ответы
Ответ 1
Если вы назовете свои элементы ui-view (например, <div ui-view="player"></div>
), вы можете настроить их в своей конфигурации $stateProvider.
Итак, учитывая следующую разметку в template.html:
<md-tabs md-selected="currentTab">
<md-tab label="Player" ui-sref="tabs.player">
<div ui-view="player"></div>
</md-tab>
<md-tab label="Map" ui-sref="tabs.map">
<div ui-view="map"></div>
</md-tab>
</md-tabs>
Вы можете настроить таргетинг на каждый элемент ui-view
(и обновить индекс currentTab) следующей конфигурацией $stateProvider:
.state('tabs', {
abstract: true,
url: '/tabs',
templateUrl: 'template.html',
controller: function($scope) {
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
$scope.currentTab = toState.data.selectedTab;
});
}
})
.state('tabs.player', {
url: '/player',
data: {
'selectedTab': 0
},
views: {
'player': {
controller: playerController
}
}
})
.state('tabs.map', {
url: '/map',
data: {
'selectedTab': 1
},
views: {
'map': {
controller: mapController
}
}
})
Теперь вам нужно определить playerController и mapController. Вы можете загрузить частичные шаблоны и т.д. В ui-view
, см. Раздел Несколько именованных видов.
Ответ 2
Мне удалось это сделать, просто сделав
index.html
<md-toolbar ng-controller="NavigationController as vm"
ng-include="'app/components/navbar/navbar.html'"
class="md-default-theme" >
</md-toolbar>
<md-content ui-view
md-scroll-y
class="md-default-theme"
role="main"
flex>
</md-content>
navbar.html
<md-tabs md-selected="vm.currentTab" md-stretch-tabs="always" class="main-toolbar">
<md-tab label="Home" ui-sref="home"></md-tab>
<md-tab label="Portfolio" ui-sref="portfolio"></md-tab>
<md-tab label="Contact" ui-sref="contact"></md-tab>
</md-tabs>
app.js
$stateProvider
.state('home', {
url: '/',
data: {
'selectedTab' : 0
},
templateUrl: 'app/components/main/main.html',
controller: 'MainController as vm'
})
.state('portfolio', {
url: '/portfolio',
data: {
'selectedTab' : 1
},
templateUrl: 'app/components/portfolio/portfolio.html',
controller: 'PortfolioController as vm'
})
.state('contact', {
url: '/contact',
data: {
'selectedTab' : 2
},
templateUrl: 'app/components/contact/contact.html',
controller: 'ContactController as vm'
});
navigation.controller.js
function NavigationController($scope) {
var vm = this;
$scope.$on('$stateChangeSuccess', function(event, toState) {
vm.currentTab = toState.data.selectedTab;
});
}
Ответ 3
Для всех, кто приходит из Google и не использует ui-router, вы можете сделать то же самое с ng-маршрутизатором по умолчанию:
В индексном файле введите код вкладок:
<md-tabs md-selected="0" ng-controller="TabCtrl">
<md-tab ng-repeat="tab in tabs" md-on-select="switchTab($index)" label="{{tab}}">
<div ng-view></div>
</md-tab>
</md-tabs>
Затем создайте TabCtrl:
// Define the titles of your tabs
$scope.tabs = ["Player", "Map"];
// Change the tab
$scope.switchTab = function(index) {
switch(index) {
case 0: $location.path('/player');break;
case 1: $location.path('/map');break;
}
}
Наконец, определите свои маршруты в своей конфигурации:
.when( '/player', {
templateUrl: 'partials/player.html',
controller: 'PlayerCtrl'
})
.when( '/map', {
templateUrl: 'partials/map.html',
controller: 'MapCtrl'
});
Ответ 4
Здесь немного изменилось с исходным документом (https://material.angularjs.org/#/demo/material.components.tabs):
Я добавил несколько комментариев. Если кто-то уйдет или обновит вашу страницу, ГЭС войдет на ту же вкладку...
HTML:
<md-tabs md-selected="selectedIndex">
<md-tab ng-repeat="tab in tabs" md-on-select="announceSelected(tab, $index)" md-on-deselect="announceDeselected(tab)" ng-disabled="tab.disabled" label="{{tab.title}}">
</md-tab>
</md-tabs>
Контроллер:
var tabs = [
{ title: 'welcome'},
{ title: 'profile'},
];
$scope.selectedIndex = 0;
// $scope.selectedIndex = parseInt($cookies.selectedIndex);
$scope.tabs = tabs;
$scope.announceSelected = function(tab, index) {
//$cookies["selectedIndex"] = index;
RedirectService.To(tab.title);
}
Factroy:
app.factory('RedirectService', function ($location){
return{
To : function(key){
return $location.path(key)
},
};
});
Ответ 5
Альтернативой, которая позволяет напрямую связываться с вкладкой и сохраняет поведение вперед и назад, является использование структуры HTML из этого ответа, затем введите $transitions
для использования слушатель onSuccess
:
angular.module('tabs', ['ngMaterial', 'ui.router'])
.config(['$stateProvider', '$urlRouterProvider',
($stateProvider, $urlRouterProvider) => {
$stateProvider
.state('home', {
url: '/',
data: { selectedTab: 0 },
template: '<p>HOME</p>',
})
.state('portfolio', {
url: '/portfolio',
data: { selectedTab: 1 },
template: "<p>'FOLIO</p>",
})
.state('contact', {
url: '/contact',
data: { selectedTab: 2 },
template: "<p>'TACT</p>",
})
}
])
.controller('NavigationController', function($scope, $transitions) {
$transitions.onSuccess({},
function(transition) {
var $state = transition.router.stateService
var currentTab = $state.$current.data.selectedTab
$scope.selectedTab = currentTab
}
)
})
Рабочий пример: https://dysbulic.github.io/angular-tabs/