1

I am creating an AngularJS application that is a web planner that consists of 6 steps. Each step has its own view and its own controller. There is some data that should be accessible from all states (There is Order level information that is used in the header/title of the planner). I have put this information in a service, but the problem is in this root controller, it does not have access to the $stateParams which is how I know whether or not API data needs to be fetched.

I could use $scope.$emit() or $scope.$broadcast to tell my root controller when ui.router runs and finds the ID in the URL, but that just seems like bad design. What is the best way to make the $stateParams available to a global controller?

Here is what the HTML looks like.

<div ng-app="MyApp.SubModule.Module" ng-controller="RootController">

    <sk-overlay ng-show="overlayVisible"></sk-overlay>



    <h2 class="dashTitle"> {{ (Order.CustomerInfo.CompanyName ? '- ' + Order.CustomerInfo.CompanyName : '') }}</h2>
    <div id="wpMenuContainer" class="wpMenuContainer">
        <ul class="wpMenu clearfix">
            <li ng-repeat="chevron in Chevrons" ng-class="{ active : chevron.active, navable : $index < Index }" ng-click="!($index < Index)||navigate(chevron, $index)">

                <span>{{ chevron.name }}</span>
            </li>

          </ul>
    </div>





    <div ui-view class="do"></div>




</div>

I want RootController to be used to control data that is global to the entire application, but that state does not exist in the $stateProvider, therefore it does not get access to the $stateParams variables.

Matt Hintzke
  • 7,744
  • 16
  • 55
  • 113

2 Answers2

1

You could always use a shared service (I think I actually mean factory here) to enable two way communication between different controlers.
This is a hot topic and there are lots of related questions on this:

Update
You could actually make that factory global by assigning it to the $rootScope, thus being able to observe it without having to assign it in every controller:

angular.module('app')
    .factory('sharedData', function() {
        return {};
    })
    .controller('mainController', function($rootScope, sharedData) {
        $rootScope.sharedData = sharedData;
        $rootScope.$watch('sharedData', updateMyStuff, true);
    })
    .controller('subController', function(sharedData) {
        sharedData.stateParams = 'inaccessible stuff';
    });
Community
  • 1
  • 1
gion_13
  • 41,171
  • 10
  • 96
  • 108
  • If you read my post, I state that I am using a service.. But I don't want to have to assign the Order information in each controller even though it is only needed in 1 place. There should be a solution that requires only a single `$scope.Order = OrderService` and then is not needed again. – Matt Hintzke Sep 22 '14 at 19:46
  • I understand what you mean, but this still requires me to set up the shared data in each of my controllers because the user can come to any page of the planner at any given time. – Matt Hintzke Sep 22 '14 at 20:03
0

$stateParams can be injected into any of your controllers/services/directives using DI, it is a services that is provided by ui-router.

$state can also be injected into any of your controllers/services/directives using DI, it is a services that is provided by ui-router. You can access stateParams through $state via $state.params

Also, ui-router mentions that it is handy to set up $state in $rootScope on run() so that it can be access primarily in templates.

TheSharpieOne
  • 25,646
  • 9
  • 66
  • 78