I need to be able to specify different layouts for different routes, and most preferably I would like to be able to define layouts and other parameters in an object in route config and have them propagate on route change.
Looks like https://github.com/angular-ui/ui-router from the Angular team is the best approach.
Here's the way I solved it in my current project.
Working demo to be found here
What if you could define objects in your $routeProvider.when(...)
block like this:
Route definition:
$routeProvider
.when('/', {
templateUrl: 'main.html',
controller: 'MainCtrl',
resolve: {
interceptor: interceptWith('routeChangeInterceptor', {
stateClass: {
fullWidthLayout: true
}
})
}
});
And have them propagate and use it to add classes with an ng-class
like interface using the stateClass objects like this?
HTML:
<body state-class="{'full-width-layout': fullWidthLayout}"> ... </body>
<div class="some-class" state-class="{'some-class': someValue}"> ... </div>
How to:
This is using an interceptWith(...)
helper that simply injects a service and calls it with given parameters, but it could also be implemented using array notation like this
interceptor: ['serviceToInject', function(injectedService) { .. }];
Only this way It's DRYer. See demo fore more on this.
The service that is used to broadcast the object from the route definition:
//This interceptor is responsible for emiting an event on rootScope
.factory('routeChangeInterceptor', ['$rootScope', function($rootScope) {
var _prepare = function(state) {
$rootScope.$broadcast('data:broadcast-state', state);
};
return {
prepare: _prepare
};
}]);
The directive used to add/remove classes based on the broadcasted state event object looks like this:
//This directive receives and $parses object/classname mappings,
//and it will add or remove the defined class for every mapping that is defined.
angular.module('broadcastState')
.directive('stateClass', ['$parse', function ($parse) {
var _linkFn = function link(scope, element, attrs) {
scope.$on('data:broadcast-state', function(e, state) {
//Set defaults
state = state || {};
state.stateClass = state.stateClass || {};
var classes = $parse(attrs.stateClass)(state.stateClass);
angular.forEach(classes,function(value,className) {
if(value && typeof value === 'boolean')
{
element.addClass(className);
}
else
{
element.removeClass(className);
}
});
});
}
return {
restrict: 'A',
link: _linkFn
};
}]);
Check out the plnkr to read more.
Looks like https://github.com/angular-ui/ui-router from the Angular team is the best approach.
Try this http://angular-route-segment.com/ (A lightweight extension for AngularJS $route service which supports tree-like nested views and routes, and advanced flow handling)
© 2022 - 2024 — McMap. All rights reserved.