Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've never used Angular UI Router before but I want to build an application that has nested views so it looks like the most sensible choice. However. I just can't get my head around it. My application is modular so I have an element on my page that I want the other modules, with their view templates, to load into.

Application wireframe

Then when some action is taken inside one of the nested views, say a button click, I would like the state to change so that module to becomes the only one inside the main view, and for the URL to change:

Application wireframe - with state change

I'm writing in CoffeeScript and using Browserify to tie the app together, so all the modules are in separate files and required in. This is where I've got so far but it's not working and I can't figure it out.

app.coffee

require...
require...
require...

app = angular.module("darrylsnow", [
    "ngAnimate"
    "ui.router"
    "submodule1"
    "submodule2"
    "templates"
]).config [
    "$stateProvider"
    "$urlRouterProvider"
    "$locationProvider"
    ($stateProvider, $urlRouterProvider, $locationProvider) ->

        $urlRouterProvider
            .otherwise "/"

        $stateProvider
            .state "main",
                abstract: true  # because the main module requires the submodules
                url: "/"

        $locationProvider.html5Mode true
]

submodule1.coffee

submodule1 = angular.module("submodule1", [
    "ui.router"
]).config [
    "$stateProvider"
    "$urlRouterProvider"
    "$routeProvider"
    ($stateProvider, $urlRouterProvider, $routeProvider) ->

        $stateProvider
            .state "main.submodule1",
                url: ""
                templateUrl: "submodule1.html"
            .state "main.submodule1-expanded",
                url: "/submodule1" # template shouldn't change

]

submodule2.coffee

submodule2 = angular.module("submodule2", [
    "ui.router"
]).config [
    "$stateProvider"
    "$urlRouterProvider"
    "$routeProvider"
    ($stateProvider, $urlRouterProvider, $routeProvider) ->

        $stateProvider
            .state "main.submodule2",
                url: ""
                templateUrl: "submodule2.html"
            .state "main.submodule2-expanded",
                url: "/submodule2" # template shouldn't change

]

Is it even possible to have child states in different modules? If not how would you recommend I do it? Thanks.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

There is a working example, where I tried to show how to put angular, ui-router and coffee together. While I am not 100% sure what exactly you were trying to achieve ... you can find some answers and inspiration there.

Firstly the (simplified) index.html

  <head> 
    ...
    <script src="app.js"></script>
    <script src="submodule1.js"></script> 
    <script src="submodule2.js"></script>     
  </head>

  <body>
   <ul>    
    <a ui-sref="main.submodule1.expanded">main.submodule1.expanded</a>
    <a ui-sref="main.submodule2({id:22})">main.submodule2</a>
    <a ui-sref="main.submodule2-expanded({id:22})">main.submodule2-expanded</a>
    <div ui-view=""></div>
  </body>

Now, this would be the app.coffee, where the most important part is the template. That will allow each child to inject its view into this unnamed view template. The other option would be to use absolutely named views, but this keeps it simple:

app = angular.module("darrylsnow", [
    "ui.router"
    "submodule1"
    "submodule2"
]).config [
    "$stateProvider"
    "$urlRouterProvider"
    "$locationProvider"
    ($stateProvider, $urlRouterProvider, $locationProvider) ->

        $stateProvider
            .state "main",
                template: "<div ui-view />"
                abstract: true  # because the main module requires the submodules
                url: "/" 
     ...

The other files represents really different modules.

The example of submodule1.coffeee shows that even here we are using nesting (the main.submodule1.expanded is child of main.submodule1):

submodule1 = angular.module("submodule1", [
    "ui.router"
]).config [
    "$stateProvider"
    "$urlRouterProvider"
    "$locationProvider"
    ($stateProvider, $urlRouterProvider, $locationProvider) ->

        $stateProvider
            .state "main.submodule1",
                template: "<div ui-view />"
                abstract: true
            .state "main.submodule1.expanded",
                url: "/submodule1" # template shouldn't change
                templateUrl: "submodule1.html"
                controller: 'Some1Ctrl'

] 
submodule1.controller 'Some1Ctrl', [  
    "$scope"
    "$stateParams"
    "$state"
    ($scope, $stateParams, $state) ->
        $scope.params = $stateParams;
        $scope.state = $state.current;
]

As a different approach we can use siblings as the submodule2.coffee shows:

submodule2 = angular.module("submodule2", [
    "ui.router"
]).config [
    "$stateProvider"
    "$urlRouterProvider"
    "$locationProvider"
    ($stateProvider, $urlRouterProvider, $locationProvider) ->

        $stateProvider
            .state "main.submodule2",
                templateUrl: "submodule2.html"
                controller: 'Some2Ctrl'
            .state "main.submodule2-expanded",
                url: "/submodule2/{id}" # template shouldn't change
                templateUrl: "submodule2.html"
                controller: 'Some2Ctrl'
       ...

Well how that all fits together is the best to observe in this plunker

share|improve this answer
1  
thanks, I get it now! –  Darryl Snow Jun 20 at 2:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.