-
-
Save JohannesRudolph/47e5c58128c0ff31bccc to your computer and use it in GitHub Desktop.
Jqm Angular adapter page loader using custom routing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module( "...", ["$pageLoader", "logfilesServices"] ) | |
.config( ['$pageLoaderProvider', function( $pageLoaderProvider ) { | |
$pageLoaderProvider | |
.when( 'logfiles', { templateUrl: 'partials/logfiles.html' } ) | |
.when( 'logfiles/:logfileId', { templateUrl: 'partials/logfile.html' } ) | |
.otherwise( { redirectTo: '' } ) | |
.when( '', { templateUrl: '#index' } ); | |
}] ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The pageloader is largely inspired by angulars ngRoute service | |
function $PageLoaderProvider() { | |
var routes = {}; | |
this.when = function( path, route ) { | |
routes[path] = route; | |
// create redirection for trailing slashes | |
if ( path ) { | |
var redirectPath = ( path[path.length - 1] == '/' ) | |
? path.substr( 0, path.length - 1 ) | |
: path + '/'; | |
routes[redirectPath] = { redirectTo: path }; | |
} | |
return this; | |
} | |
this.otherwise = function( params ) { | |
this.when( null, params ); | |
return this; | |
}; | |
this.$get = ['$rootScope', '$location', '$routeParams', '$q', '$injector', '$http', '$templateCache', | |
function( $rootScope, $location, $routeParams, $q, $injector, $http, $templateCache ) { | |
var matcher = switchRouteMatcher; | |
var $pageLoader = { | |
routes: routes, | |
}; | |
var jqmLoadPage = $.mobile.loadPage; | |
$.mobile.loadPage = function( url, options ) { | |
var match = url.match(/#(\w+)/); // match everything after the hash | |
if ( match ) { | |
var path = match[1]; | |
// check whether the requested page matches on of our routes | |
var next = parseRoute( path, $location.search() ); | |
if ( next ) { | |
var template; | |
if ( angular.isDefined( template = next.template ) || angular.isDefined( template = next.templateUrl ) ) { | |
url = template; | |
} | |
} | |
} | |
return jqmLoadPage( url, options ); | |
}; | |
return $pageLoader; | |
///////////////////////////////////////////////////// | |
function switchRouteMatcher( on, when ) { | |
// TODO(i): this code is convoluted and inefficient, we should construct the route matching | |
// regex only once and then reuse it | |
var regex = '^' + when.replace( /([\.\\\(\)\^\$])/g, "\\$1" ) + '$', | |
params = [], | |
dst = {}; | |
angular.forEach( when.split( /\W/ ), function( param ) { | |
if ( param ) { | |
var paramRegExp = new RegExp( ":" + param + "([\\W])" ); | |
if ( regex.match( paramRegExp ) ) { | |
regex = regex.replace( paramRegExp, "([^\\/]*)$1" ); | |
params.push( param ); | |
} | |
} | |
} ); | |
var match = on.match( new RegExp( regex ) ); | |
if ( match ) { | |
angular.forEach( params, function( name, index ) { | |
dst[name] = match[index + 1]; | |
} ); | |
} | |
return match ? dst : null; | |
} | |
function loadNextPage() { | |
var next = parseRoute( $location.path(), $location.search() ), | |
last = $pageLoader.current; | |
if ( next || last ) { | |
$pageLoader.current = next; | |
$q.when( next ). | |
then( function() { | |
if ( next ) { | |
var keys = [], | |
values = [], | |
template; | |
angular.forEach( next.resolve || {}, function( value, key ) { | |
keys.push( key ); | |
values.push( isString( value ) ? $injector.get( value ) : $injector.invoke( value ) ); | |
} ); | |
if ( angular.isDefined( template = next.template ) ) { | |
} else if ( angular.isDefined( template = next.templateUrl ) ) { | |
template = $http.get( template, { cache: $templateCache } ). | |
then( function( response ) { return response.data; } ); | |
} | |
if ( angular.isDefined( template ) ) { | |
keys.push( '$template' ); | |
values.push( template ); | |
} | |
return $q.all( values ).then( function( values ) { | |
var locals = {}; | |
angular.forEach( values, function( value, index ) { | |
locals[keys[index]] = value; | |
} ); | |
return locals; | |
} ); | |
} | |
} ). | |
// after route change | |
then( function( locals ) { | |
if ( next == $pageLoader.current ) { | |
if ( next ) { | |
next.locals = locals; | |
angular.copy( next.params, $routeParams ); | |
} | |
$rootScope.$broadcast( '$pageLoadSuccess', next, last ); | |
} | |
}, function( error ) { | |
if ( next == $pageLoader.current ) { | |
$rootScope.$broadcast( '$pageLoadError', next, last, error ); | |
} | |
} ); | |
} | |
} | |
// copied straight from Angular.js (not exposed publicly) | |
function inherit( parent, extra ) { | |
return angular.extend( new ( angular.extend( function() { }, { prototype: parent } ) )(), extra ); | |
} | |
/** | |
* @returns the current active route, by matching it against the URL | |
*/ | |
function parseRoute( targetPath, targetSearch ) { | |
// Match a route | |
var params, match; | |
angular.forEach( routes, function( route, path ) { | |
if ( !match && ( params = matcher( targetPath, path ) ) ) { | |
match = inherit( route, { | |
params: angular.extend( {}, targetSearch, params ), | |
pathParams: params | |
} ); | |
match.$pageLoader = route; | |
} | |
} ); | |
// No route matched; fallback to "otherwise" route | |
return match || routes[null] && inherit( routes[null], { params: {}, pathParams: {} } ); | |
} | |
/** | |
* @returns interpolation of the redirect path with the parametrs | |
*/ | |
function interpolate( string, params ) { | |
var result = []; | |
angular.forEach(( string || '' ).split( ':' ), function( segment, i ) { | |
if ( i == 0 ) { | |
result.push( segment ); | |
} else { | |
var segmentMatch = segment.match( /(\w+)(.*)/ ); | |
var key = segmentMatch[1]; | |
result.push( params[key] ); | |
result.push( segmentMatch[2] || '' ); | |
delete params[key]; | |
} | |
} ); | |
return result.join( '' ); | |
} | |
}]; | |
} | |
angular.module( "$pageLoader", [], function( $provide ) { | |
$provide.provider( { | |
$pageLoader: $PageLoaderProvider | |
} ); | |
} ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment