<!DOCTYPE html>
<html ng-app="optional">
<head>
<script data-require="angular.js@1.3.1" data-semver="1.3.1" src="//code.angularjs.org/1.3.1/angular.js"></script>
<script src="//unpkg.com/angular-ui-router/release/angular-ui-router.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="angular-ui-router.js"></script>
<script src="script.js"></script>
</head>
<body>
<h5>Squash settings:</h5>
<pre>{{ href | json }}</pre>
<h5>Current state / params:</h5>
<pre>{{ $state.current.name }} -
{{$state.params | json }}</pre>
<!-- <h5>Current url:</h5>
<pre>{{ $location.url() }}</pre>
-->
<ul>
<li ui-sref-active="active" ui-sref="user({username: 'christopherthielen'})">user({username: 'christopherthielen'})</li>
<li ui-sref-active="active" ui-sref="user({username: 'johndoe'})">user({username: 'johndoe'})</li>
<li ui-sref="user({username: ''})">user({username: ''})</li>
<li ui-sref="user({username: null})">user({username: null})</li>
<li ui-sref="user" ui-sref-opts="{ inherit: false }">user(), { inherit: false}</li>
<li ui-sref="user" ui-sref-opts="{ inherit: true }">user(), { inherit: true}</li>
</ul>
<div>
<button type="button" ng-click="reload()">$state.reload()</button>
<button type="button" ng-click="go()">$state.go('user')</button>
</div>
<div ui-view></div>
</body>
</html>
// Code goes here
var app = angular.module("optional", ['ui.router']);
app.service("Session", function() {
return { username: 'christopherthielen' };
});
app.config(function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider) {
$urlRouterProvider.otherwise("/user/christopherthielen/gallery/favorites/photo/CN0ZRJw");
$urlMatcherFactoryProvider.defaultSquashPolicy(false);
// $urlMatcherFactoryProvider.defaultSquashPolicy("");
// $urlMatcherFactoryProvider.defaultSquashPolicy(true);
$stateProvider.decorator("url", function(state, urlFn) {
var url = urlFn(state);
url.$$format = function(squash, params) {
var keys = url.params.$$keys();
var original = keys.map(function(key) { return url.params[key].squash; });
keys.forEach(function(key) { url.params[key].squash = squash; });
var formatted = url.format(params);
for (var i = 0; i < keys.length; i++) { url.params[keys[i]].squash = original[i]; }
return formatted;
}
return url;
});
$stateProvider.state({
name: 'top', url: "/", template: '<div ui-view/>',
resolve: {
users: function($http) {
return $http.get("users.json").then(function(r) { return r.data; });
},
photos: function($http) {
return $http.get("photos.json").then(function(r) { return r.data; });
}
}
});
$stateProvider.state({
name: "user",
url: "user/:username",
parent: 'top',
params: {
username: {
value: function(Session) { return Session.username; }
}
},
resolve: {
user: function($stateParams, users) { return users[$stateParams.username]; },
galleries: function($stateParams, photos) { return photos[$stateParams.username] }
},
templateUrl: 'user.html',
controller: function($scope, $state, user, galleries) { $scope.user = user; $scope.galleries = galleries; }
});
$stateProvider.state({
name: "user.gallery",
url: "/gallery/:galleryid",
resolve: {
photos: function($stateParams, galleries) { return galleries[$stateParams.galleryid]; }
},
params: { galleryid: { value: "favorites" } },
templateUrl: 'gallery.html',
controller: function($scope, $state, $stateParams, photos) {
$scope.gallery = $stateParams.galleryid;
$scope.photos = photos;
}
});
$stateProvider.state({
name: "user.gallery.photo",
url: "/photo/:photoid",
resolve: {
photo: function($stateParams, photos) {
return photos.filter(function(photo) { return photo.id === $stateParams.photoid; })[0];
}
},
templateUrl: 'photo.html',
controller: function($scope, $state, $stateParams, photo) {
$scope.gallery = $stateParams.galleryid;
$scope.photo = photo;
}
});
});
app.run(function($rootScope, $location, $state) {
$rootScope.$location = $location;
$rootScope.$state = $state;
$rootScope.reload = function() { $state.reload(); };
$rootScope.go = function() { $state.go('user'); };
});
// Adds state change hooks; logs to console.
app.run(function($rootScope, $state, $stateParams, $urlMatcherFactory) {
$rootScope.$state = $state;
var umf = $urlMatcherFactory;
$rootScope.href = {};
$rootScope.$on("$stateChangeSuccess", function(evt, to, toP, from, fromP) {
[ false, "-", "~", "", true ].forEach(function(policy) {
$rootScope.href[policy] = $state.$current.url.$$format(policy, $stateParams);
})
});
// function setSquash(state, squash) {
// var reset = {};
// var params = state.params;
// params.$$keys().forEach(function(key) {
// reset[key] = params[key].squash;
// params[key].squash = squash;
// });
// return function() { angular.forEach(reset, function(value, key) { params[key].squash = reset[key]}) }
// }
// $rootScope.href = {};
// angular.forEach( [ "nosquash", "value", "slash" ], function(policy) {
// var resetFn = [];
// angular.forEach($state.$current.path, function(state) {
// resetFn.push(setSquash(state, policy));
// })
// $rootScope.href[policy] = $state.$current.url.format($stateParams);
// resetFn.forEach(function(fn) { fn(); } );
// });
// });
function message(to, toP, from, fromP) { return from.name + angular.toJson(fromP) + " -> " + to.name + angular.toJson(toP); }
$rootScope.$on("$stateChangeStart", function(evt, to, toP, from, fromP) { console.log("Start: " + message(to, toP, from, fromP)); });
$rootScope.$on("$stateChangeSuccess", function(evt, to, toP, from, fromP) { console.log("Success: " + message(to, toP, from, fromP)); });
$rootScope.$on("$stateChangeError", function(evt, to, toP, from, fromP, err) { console.log("Error: " + message(to, toP, from, fromP), err); });
});
/* Styles go here */
ul li {
display: inline-block;
margin: 0.2em;
padding: 0.1em 0.75em 0.1em 0.75em;
border: 1px solid black;
background-color: #DDDDff;
border-radius: 4px;
text-decoration: underline;
cursor: pointer
}
ul li.active {
background-color: #AAAAFF;
}
{
"christopherthielen": {
"username": "christopherthielen",
"name": "Chris Thielen"
},
"johndoe": {
"username": "johndoe",
"name": "John Doe"
}
}
<h3>User: {{ user.name || "no user" }}</h3>
<ul>
<li ui-sref-active="active"
ui-sref="user.gallery({galleryid: gallery })"
ng-repeat="(gallery, photos) in galleries">
<a>{{gallery}}</a>
</li>
</ul><div ui-view></div>
{
"christopherthielen": {
"favorites": [
{ "id": "CN0ZRJw", "name": "putin", "url": "http://i.imgur.com/CN0ZRJw.gif" },
{ "id": "TjjgkZW", "name": "homer", "url": "http://i.imgur.com/TjjgkZW.gif" }
],
"skiing": [
{ "id": "BjWLA", "name": "spread eagle", "url": "http://i.imgur.com/BjWLA.jpg" },
{ "id": "uU2iY0X", "name": "faceplant", "url": "http://i.imgur.com/uU2iY0X.jpg" }
],
"dogs": [
{ "id": "yK3WE7P", "name": "weiner", "url": "http://i.imgur.com/yK3WE7P.jpg" },
{ "id": "n4V9UXT", "name": "Oliphaunt", "url": "http://i.imgur.com/n4V9UXT.jpg" }
]
},
"johndoe": {
"favorites": [
{ "id": "1WjYutp", "name": "fireworks", "url": "http://i.imgur.com/1WjYutp.jpg" },
{ "id": "USnLRR0", "name": "killer penguin", "url": "http://i.imgur.com/USnLRR0.jpg" }
],
"fruit": [
{ "id": "NMLpcKj", "name": "strawberry", "url": "http://i.imgur.com/NMLpcKj.jpg" },
{ "id": "e4bnu7i", "name": "ananas", "url": "http://i.imgur.com/e4bnu7i.jpg" }
]
}
}
<hr>
<div>Gallery: {{ gallery }}</div>
<ul>
<li ui-sref=".photo({ photoid: photo.id })"
ui-sref-active="active"
ng-repeat="photo in photos">
<a>{{ photo.name }}</a>
</li>
</ul>
<div ui-view></div>
<h3>img: {{ photo.name }}</h3>
<img style="max-width: 100%" src="{{ photo.url }} ">