Angular ui - tab controllers executed multiple times

When I click on the tab, the corresponding controller starts 4 times. What is it?

eg. The DetailsPersonController init function is executed 4 times. It should only be set after loading the tab.

HTML Tabs:

 <tabset> <tab ng-repeat="tab in vm.tabs()" heading="{{ tab.text | translate }}" ui-sref="p.search.details.{{ tab.id }}" active="tab.active"> <div ui-view="tabContent"></div> </tab> </tabset> 

States:

 .state( "p.search.details", { url: "/details", abstract: true, templateUrl: "app/modules/partials/p/search/details/details.html", controller: "DetailsController", controllerAs: "vm" } ) .state( "p.search.details.person", { url: "/person", views: { "tabContent": { templateUrl: "app/modules/partials/p/search/details/person/person.html", controller: "DetailsPersonController", controllerAs: "vm" } } } ) .state( "p.search.details.details", { url: "/details", views: { "tabContent": { templateUrl: "app/modules/partials/p/search/details/details/details.html", controller: "DetailsDetailsController", controllerAs: "vm" } } } ) .state( "p.search.details.driver", { url: "/driver", views: { "tabContent": { templateUrl: "app/modules/partials/p/search/details/driver/driver.html", controller: "DetailsDriverController", controllerAs: "vm" } } } ) .state( "p.search.details.tests", { url: "/tests", views: { "tabContent": { templateUrl: "app/modules/partials/p/search/details/tests/tests.html", controller: "DetailsTestsController", controllerAs: "vm" } } } ) 
+5
source share
3 answers

You have ui-view in the wrong place that requested the tab using vm.tabs() .

As there are 4 tags because of ng-repeat rendered div 4 times, because it placed the tab element which will be repeated using ng-repeat .

As a ui-view directives are displayed on the page 4 times, which check the browser URL and request the fact that has 4 tabs , so the entire controller with the template received 4 times in your application.

Markup

  <tabset> <tab ng-repeat="tab in vm.tabs()" heading="{{ tab.text | translate }}" ui-sref="p.search.details.{{ tab.id }}" active="tab.active"> </tab> </tabset> <div ui-view="tabContent"></div> 
+5
source

Solution: take care of where to place the ui-view . It must not be within the <tab>

 <tabset> <tab ng-repeat="tab in vm.tabs" heading="{{ tab.text | translate }}" ui-sref="p.search.details.{{ tab.id }}" active="tab.active"> </tab> </tabset> <div ui-view></div> 

I did this with this example and changed it: http://plnkr.co/edit/efnfjoQ8Hft6AZITCR67?p=preview

 .state('DocumentoMasterView', { url: "/route2", templateUrl: "route2.html", controller:'myAppController' }) .state('DocumentoMasterView.A', { url: '/detail', templateUrl: 'route2.A.view.html', controller:'myAppControllerA' }) .state('DocumentoMasterView.B', { url: '/image', templateUrl: 'route2.B.view.html', controller:'myAppControllerB' }) 

and

 $scope.go = function(route){ $state.go(route); }; $scope.active = function(route){ return $state.is(route); }; $scope.$on('$stateChangeSuccess', function() { console.log($state); $scope.tabs.forEach(function(tab) { tab.active = $scope.active(tab.route); }); }); 
+3
source

Just to complete the already proposed solution, moving the external ui-view tab can create css problems (this was in my case), so the solution is to keep the ui-view inside the tab and add an ng-if ui-view div so that as a result, html contains only one ui-view div.

NB: ng-if cannot be replaced with ng-show / ng-hide.

0
source

All Articles