Initial working version of router based nav controller

This commit is contained in:
Max Lynch
2013-11-18 18:05:21 -06:00
parent 767d22812c
commit 2ea66ecfb3
4 changed files with 380 additions and 0 deletions

View File

@ -0,0 +1,128 @@
(function() {
'use strict';
/**
* @description
* The NavController is a navigation stack View Controller modelled off of
* UINavigationController from Cocoa Touch. With the Nav Controller, you can
* "push" new "pages" on to the navigation stack, and then pop them off to go
* back. The NavController controls a navigation bar with a back button and title
* which updates as the pages switch.
*
* The NavController makes sure to not recycle scopes of old pages
* so that a pop will still show the same state that the user left.
*
* However, once a page is popped, its scope is destroyed and will have to be
* recreated then next time it is pushed.
*
*/
var actualLocation = null;
angular.module('ionic.ui.navRouter', [])
.run(['$rootScope', function($rootScope) {
$rootScope.stackCursorPosition = 0;
}])
.directive('navRouter', ['$rootScope', '$location', '$window', '$route', function($rootScope, $location, $window, $route) {
return {
restrict: 'AC',
link: function($scope, $element, $attr) {
$scope.animation = $attr.animation;
$element.addClass($scope.animation);
$scope.isReverse = false;
var reverseTransition = ionic.throttle(function() {
console.log('REVERSE');
$element.removeClass($scope.animation);
$element.addClass($scope.animation + '-reverse');
}, 1000, {
})
var forwardTransition = ionic.throttle(function() {
console.log('FORWARD');
$element.removeClass($scope.animation + '-reverse');
$element.addClass($scope.animation);
}, 1000, {
});
$scope.$on('$routeChangeSuccess', function(e, a) {
console.log('ROUTE CHANGED', a, e);
});
$scope.$on('$routeChangeStart', function(e, a) {
console.log('ROUTE START', a, e);
var back, historyState = $window.history.state;
back = !!(historyState && historyState.position <= $rootScope.stackCursorPosition);
if(back) {
reverseTransition();
} else {
forwardTransition();
}
});
$scope.$on('$locationChangeSuccess', function() {
// Store the new location
console.log('LOCATION CHANGE SUCCESS');
$rootScope.actualLocation = $location.path();
});
// Keep track of location changes and update a stack pointer that tracks whether we are
// going forwards or back
$scope.$watch(function () { return $location.path() }, function (newLocation, oldLocation) {
if($rootScope.actualLocation === newLocation) {
var back, historyState = $window.history.state;
back = !!(historyState && historyState.position <= $rootScope.stackCursorPosition);
if (back) {
//back button
$rootScope.stackCursorPosition--;
} else {
//forward button
$rootScope.stackCursorPosition++;
}
} else {
var currentRouteBeforeChange = $route.current;
if (currentRouteBeforeChange) {
$window.history.replaceState({
position: $rootScope.stackCursorPosition
});
$rootScope.stackCursorPosition++;
}
}
});
}
}
}])
.directive('navBack', ['$window', function($window) {
return {
restrict: 'AC',
require: '^?navRouter',
link: function($scope, $element, $attr, navCtrl) {
var goBack = function() {
$window.history.back();
};
$element.bind('tap', goBack);
$element.bind('click', goBack);
$scope.$on('$destroy', function() {
$element.unbind('tap', goBack);
$element.unbind('click', goBack);
});
}
}
}]);
})();

View File

@ -16,6 +16,7 @@ angular.module('ionic.ui', [
'ionic.ui.content',
'ionic.ui.tabs',
'ionic.ui.nav',
'ionic.ui.navRouter',
'ionic.ui.header',
'ionic.ui.sideMenu',
'ionic.ui.slideBox',
@ -31,6 +32,7 @@ angular.module('ionic', [
// Angular deps
'ngAnimate',
'ngRoute',
'ngTouch',
'ngSanitize'
]);

View File

@ -0,0 +1,119 @@
<html ng-app="navTest">
<head>
<meta charset="utf-8">
<title>Nav Bars</title>
<!-- Sets initial viewport load and disables zooming -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="/vendor/font-awesome/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="../../../../dist/css/ionic.css">
<script src="../../../../dist/js/ionic.js"></script>
<script src="../../../../dist/js/ionic-angular.js"></script>
<style>
.view-animate > .ng-enter, .view-animate > .ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 250ms;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 250ms;
display:block;
width:100%;
border-left:1px solid black;
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
padding:10px;
}
.view-animate > .ng-enter {
-webkit-transform: translate3d(100%, 0, 0);
}
.view-animate > .ng-enter.ng-enter-active {
-webkit-transform: translate3d(0, 0, 0);
}
.view-animate > .ng-leave.ng-leave-active {
-webkit-transform: translate3d(-100%, 0, 0);
}
.view-animate-reverse > .ng-enter, .view-animate-reverse > .ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 250ms;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 250ms;
display:block;
width:100%;
border-left:1px solid black;
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
padding:10px;
}
.view-animate-reverse > .ng-enter {
-webkit-transform: translate3d(-100%, 0, 0);
}
.view-animate-reverse > .ng-enter.ng-enter-active {
-webkit-transform: translate3d(0%, 0, 0);
}
.view-animate-reverse > .ng-leave.ng-leave-active {
-webkit-transform: translate3d(100%, 0, 0);
}
</style>
</head>
<body>
<pane nav-router animation="view-animate">
<ng-view></ng-view>
</pane>
<script id="page1.html" type="text/ng-template">
<pane>
<h1>Page 1</h1>
<a class="button button-pure" nav-back>Back</a>
<a class="button button-assertive" href="#/page2">Next</a>
</pane>
</script>
<script id="page2.html" type="text/ng-template">
<pane>
<h1>Page 2</h1>
<a class="button button-pure" nav-back>Back</a>
<a class="button button-assertive" href="#/page3">Next</a>
</pane>
</script>
<script id="page3.html" type="text/ng-template">
<pane>
<h1>Page 3</h1>
<a class="button button-pure" nav-back>Back</a>
</pane>
</script>
<script>
angular.module('navTest', ['ionic'])
.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/page1', {
templateUrl: 'page1.html',
});
$routeProvider.when('/page2', {
templateUrl: 'page2.html',
});
$routeProvider.when('/page3', {
templateUrl: 'page3.html',
});
$routeProvider.otherwise({
redirectTo: '/page1'
});
// configure html5 to get links working on jsfiddle
//$locationProvider.html5Mode(true);
});
</script>
</body>
</html>