This post assumes familiarity with building AngularJS applications and and AngularJS MVC.
If you have played with AngularJS a bit, you would know that you cannot share data between controllers other than through services. Sharing data through services would not be my first choice of implementation as it has pit falls that come along with maintaining state; like initialization, reset etc.
This is okay for most usecases, but seriously stands in the way of building wizards. Wizards require you to gather the data in steps and make one final server call with the data you’ve collected through all those steps.
One possible solution apart from sharing data using services is to flatten /combine all the steps into one route. Then with child controllers (one for each step), you have access to scope of the parent controller (that which controls the route); since, the scopes of the child controllers inherit prototypically from the scope of the parent controller.You could then store all the data in the scope of the parent controller. This avoids the need to use services and therefore much less messier.
Once you combine all the steps under one route, you can no longer use the browser back button to go to previous steps as the step no longer has a route of its own. The solution is to add a search param called step to the url. The value of the param should be the currently displayed step. Navigating to the subsequent steps should be driven by changing the value of the search param. This way, when you click the back button, you would be taken to the previous step instead of a completely different route.
Another problem with using child controllers is that they are initialized as soon as the route loads. This could be a problem when you need the data in a previous step to initialize the controller for the current step. This you could avoid by placing the ng-controller directive inside the ng-switch directive which switches on the current step value from search param. Since ng-switch attaches the child elements to the dom only for the matching case(in this case, a step), the controller for the step will be initialized only when the user enters the current step and you’d have access to all the data entered in the previous step from the scope of the parent controller(where you should have saved it).