John McArthur
John McArthur

Reputation: 1024

Getting nested views to work with multiple modules in AngularJS and ui-router

I'm working with a large AngularJS application, which has 1 large module, which I'm trying to break down into more easily managed modules.

We have several ui-views on the main page for menu, footer, content, sidebar etc.

At the moment each $stateProvider.state is populating each of these ui-views on every state change. I want to change it to only be more hierarchical and only have the root state change these. This I can do.

However, I'm having issues when I split the application into modules. I've created a Plunker to demonstrate.

(function() {

  angular
    .module("acme", ["ui.bootstrap", "ui.router", "acme.admin", "acme.stock"]);


  angular
    .module("acme")
    .config(MainModuleConfig);

  MainModuleConfig.$inject = ["$stateProvider", "$urlRouterProvider", "$locationProvider"];

  function MainModuleConfig($stateProvider, $urlRouterProvider, $locationProvider) {
    //$locationProvider.html5Mode(true);

    var root = {
      name: "root",
      url: "/",
      views: {
        "menuView": {
          templateUrl: "app/menu/menuTemplate.html",
        },
        "mainView": {
          templateUrl: "app/mainTemplate.html",
          controller: "MainController",
          controllerAs: "vm",
        }
      }
    };

    $stateProvider
      .state("root", root);

    $urlRouterProvider
      .otherwise("/");
  }


})();

(function() {

  angular
    .module("acme.admin", ["ui.router"]);

  angular
    .module("acme.admin")
    .config(AdminConfig);

  AdminConfig.$inject = ["$stateProvider", "$locationProvider"];

  function AdminConfig($stateProvider, $locationProvider) {


    var admin = {
      name: "admin",
      url: "/Admin",
      views: {
        "menuView": {
          templateUrl: "app/menu/menuTemplate.html",
        },        
        "mainView": {
          templateUrl: "app/admin/adminTemplate.html",
        }
      }
    };

    var countries = {
      name: "admin.Countries",
      url: "/Admin/Countries",
      views: {
        "adminView": {
          templateUrl: "app/admin/adminCountriesTemplate.html",
          controller: "AdminCountriesController",
          controllerAs: "vm"
        }
      }
    }

    var people = {
      name: "admin.People",
      url: "/Admin/People",
      views: {
        "adminView": {
          templateUrl: "app/admin/adminPeopleTemplate.html",
          controller: "AdminPeopleController",
          controllerAs: "vm"
        }
      }
    }


    $stateProvider
      .state("admin", admin)
      .state("admin.Countries", countries)
      .state("admin.People", people);
  }


})();

In the admin module and others, I don't want to have to set the "menuView" again, but I can't see how to reference the parent

Upvotes: 2

Views: 235

Answers (1)

John McArthur
John McArthur

Reputation: 1024

I managed to fix the issue:

First I set up the root state in the main module:

      var root = {
        name: "root",
        url:"/",
        views: {
          "menuView": {
            templateUrl: "app/menu/menuTemplate.html",
          },
                      "mainView": {
              templateUrl: "app/mainTemplate.html",
              controller: "MainController",
              controllerAs: "vm",
            }
        }
        };

Then in the child modules, I changed the main node to be a child of root and also suffixed the ui-view name with an @:

    var admin = {
      name: "root.admin",
      url: "/Admin",
      views: {
           "mainView@": {
          templateUrl: "app/admin/adminTemplate.html",
        }
      }
    };

The plunker has been updated with the working example.

Upvotes: 2

Related Questions