AngularJs: stateful client-side routing

Here is the demo that I created to request this question and inline code as requested: http://jsfiddle.net/Gncja/1/

<script type='text/ng-template' id='root.html'> <list template-id='sidebar.templateId' selected-item-id='sidebar.selectedItemId'></list> </script> <script type='text/ng-template' id='sidebar.html'> <ul style='width:100%;' class='nav nav-list bs-docs-sidenav'> <li ng-repeat='item in data' ng-class="{active:item.id==selectedItemId}"> <a ng-href='#/{{item.id}}'> <i class=icon-chevron-right></i> <span ng-bind='item.text'></span> </a> </li> </ul> </script> <body ng-app='main'> <div ng-view></div> </body>​ function RootCtrl($scope, $routeParams){ $scope.sidebar = { templateId: 'sidebar', selectedItemId: $routeParams.navItemId }; } RootCtrl.$inject = ['$scope','$routeParams']; angular.module('main', []). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/:navItemId', { templateUrl: 'root.html', controller: RootCtrl }). otherwise({redirectTo: '/1'}); }]). directive('list', function(){ return { restrict: 'E', replace: true, scope:{ 'templateId': '=', 'selectedItemId':'=' }, template:'<ng-include src="templateUrl"></ng-include>', controller: function($scope, $element, $attrs){ $scope.templateUrl = $scope.templateId + '.html'; $scope.data = [ {'id':'1', text:'lorem ipsum'}, {'id':'2', text:'dolor sit amet'}, ]; } }; });​ 

This is a small part of the application I'm working on, but it clearly shows what it is doing. There is a navigation menu on the page, the menu item is a reference to a hash that is processed by angular.js routing, which initializes the root controller, etc. It is rather difficult to describe, but the code example clearly shows this. The problem is that the entire content of the page re-displayed every time I click on a navigation menu item - routing has no state and knows nothing about the previous state. I would like to avoid this by reusing the result of displaying the navigation menu / template when the user simply moves between menu items (or browser history). Is it possible? I am sure that this is so, I just want to check if anyone has any good ideas. Thank!

UPDATE: I found something that could help me: http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm

+1
javascript angularjs url-routing
Nov 18
source share
1 answer

I would put the navigation menu outside of ng-view (so it doesn't redraw), but use the ng class in combination with location.path () to distinguish the currently selected item. For example.

 <div ng-controller="navCtrl"> <ul ...> <li ng-repeat='item in navData' ng-class="{active:isActiveRoute(item.id)}"> ... </ul> </div> <div ng-view></div> 

Then in navCtrl:

 $scope.navData = [ {'id':'1', text:'lorem ipsum'}, {'id':'2', text:'dolor sit amet'}, ]; $scope.isActiveRoute = function(route) { return '/' + route === $location.path(); }; 

Fiddle

+1
Nov 19 '12 at 18:10
source share



All Articles