Angular UI-Router:菜单切换不重载数据,Dashboard需重载状态及控制器
Got it, let's break down how to make this work exactly as you want:
1. Tweak your Dashboard menu link to force reload
In your index.html, add the ui-sref-opts attribute to the Dashboard link. This tells UI Router to reload the entire state every time you click it—even if you're already on the Dashboard:
<!-- Dashboard link: forces full reload on every click --> <a ui-sref="dashboard" ui-sref-opts="{reload: true}" class="main-menu-item">Dashboard</a> <!-- Other menu items: no reload by default (UI Router reuses existing state) --> <a ui-sref="orders" class="main-menu-item">Orders</a> <a ui-sref="customers" class="main-menu-item">Customers</a>
This handles the core behavior: switching between Orders/Customers won't reload their data, but clicking Dashboard will trigger a full refresh of its state, data, and controllers.
2. Configure states to support cached vs fresh data
In your app.js, set up your states so non-Dashboard states use cached data, while Dashboard fetches fresh data each time it loads/reloads:
angular.module('yourApp', ['ui.router']) .config(function($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/dashboard'); $stateProvider .state('dashboard', { url: '/dashboard', templateUrl: 'views/dashboard.html', controller: 'DashboardCtrl', // Resolve fresh data every time the state loads/reloads resolve: { dashboardData: function(DashboardService) { return DashboardService.getFreshDashboardMetrics(); } } }) .state('orders', { url: '/orders', templateUrl: 'views/orders.html', controller: 'OrdersCtrl', // Use cached data to avoid reloading when switching back resolve: { ordersData: function(OrdersService) { return OrdersService.getCachedOrdersList(); } } }) // Repeat similar setup for other non-Dashboard states });
3. Update controllers to handle data loading correctly
In DashboardCtrl.js (or your main controller file), ensure your data logic runs when the controller initializes—this happens every time the state reloads:
angular.module('yourApp') .controller('DashboardCtrl', function($scope, dashboardData) { // Fresh data from resolve updates automatically on state reload $scope.dashboardStats = dashboardData; // If you prefer fetching directly in the controller instead of resolve: // function loadDashboardData() { // DashboardService.getFreshDashboardMetrics().then(data => { // $scope.dashboardStats = data; // }); // } // loadDashboardData(); // Runs on init (and re-init on state reload) });
For non-Dashboard controllers like OrdersCtrl, use the cached data so switching between states doesn't re-fetch:
angular.module('yourApp') .controller('OrdersCtrl', function($scope, ordersData) { $scope.orders = ordersData; // Reuses cached data from resolve });
4. Optional: Programmatic reload if needed
If you ever need to trigger a Dashboard reload from another part of your app (like a "Refresh" button), use this snippet in any controller:
$scope.refreshDashboard = function() { $state.go('dashboard', {}, {reload: true}); };
Why this works:
- UI Router's default behavior is to reuse existing state instances when navigating to the same state—so non-Dashboard links don't reload data unless explicitly told to.
- The
{reload: true}option on the Dashboard link forces a full state reset: it re-runs all resolve functions, re-initializes the controller, and refreshes every piece of associated data.
内容的提问来源于stack exchange,提问作者tiberiu13

