1

I'm experimenting with AngularJS but I'm failing to achieve a combination of different, independent modules and nested views.

What I'm trying to do:

  • On top, one module for the navigation (completly separate from the other modules and always present by default)
  • Then, a module changing based on the URL, for the content (the easiest part)
  • But, inside the above mentioned module, another independent module for the user interface, like a search/paging toolbar. This module should be able to interact with the (dynamic) 'content' module. I'm not sure if it's better to have the toolbar in a separate template or in a nested template.

I can get parts of this to work, but not a combination of all of them. Currently, I managed to get the navigation to work (as default $state), but when I do that the two other templates just seem to fail (the controllers aren't even called)


index.html

    <html data-ng-app="myApp">
    <head>
        <meta charset="utf-8">
        <title>Test</title>
        <link rel="stylesheet" href="./css/style.min.css">
    </head>
    <body>
        <nav class="navbar navbar-fixed-top navbar-dark">
            <div class="container">

                <!-- this should replace the list below! -->
                <div class="container" data-ui-view="navigation"></div>

                <!-- this should be replaced / made dynamic -->
                <div class="navbar-container navbar-primary">
                    <ul class="nav navbar-nav">
                        <li class="nav-item active" data-ng-repeat="entry in navigation">
                            <a class="nav-link" href="#">Dashboard <span class="sr-only">(current)</span></a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Costumers</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">...</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>

        <!-- this can either be here, or inside data-ui-view="content" -->    
        <div class="container" data-ui-view="toolbar"></div>

        <div class="container" data-ui-view="content"></div>

        <script src="./js/script.min.js"></script>
    </body>
</html>

customer.html

<!-- the toolbar data-ui-view="toolbar" could be nested here too! better or worse? -->
<div class="card-columns card-columns-4">
    <div class="card" data-ng-repeat="customer in customers">
        <img class="card-img-top" data-src="..." alt="Card image cap">
        <div class="card-block">
            <h4 class="card-title">{{customer.firstname}} {{customer.lastname}}</h4>
            <p class="card-text"><small class="text-muted">{{customer.city}}, {{customer.country}}</small></p>
        </div>
    </div>
</div>

myApp.js

var routes = angular.module( 'myApp', [
    'ui.router',
    'toolbarControllers',
    'customerControllers',
    'navigationControllers'
] )

routes.config( [ '$stateProvider', '$urlRouterProvider', function( $stateProvider, $urlRouterProvider ) {

    // trying to set 'navigation' as default view for ALL states
    // other states should just inherit view:navigation and leave it as it is!
    $stateProvider
        .state( 'default', {
            abstract: true,
            views: {
                // also tried: 'navigation@'
                'navigation': {
                    templateUrl: 'view/navigation/navigation.html',
                    controller:  'NavigationController'
                }
                // no other default views, since we don't know the rest! It should be independent if possible
            }
        } )
} ] )    

customer.js

var customerControllers = angular.module( 'customerControllers', [ 'ui.router' ] )

customerControllers.config( [ '$stateProvider', '$urlRouterProvider', function( $stateProvider, $urlRouterProvider ) {

    $stateProvider
        .state( 'customers', {
            parent: 'default', // this doesn't seem to happen!
            url: '/customers',
            views: {
                /* 'navigation': {
                    templateUrl: 'view/navigation/navigation.html',
                    controller:  'NavigationController'    
                },*/
                'toolbar': {
                    templateUrl: 'view/ui/toolbar.html',
                    controller:  'ToolbarController'
                },
                'content': {
                    templateUrl: 'view/customers/list.html',
                    controller:  'CustomerListController'
                }
            }
        } )
} ] )

customerControllers.controller( 'CustomerListController', [ '$scope', '$http', function( $scope, $http ) {
    console.log('Customer controller called!') // only works if navigation doesn't work

    // get the data
} ] )

toolbar.js

var toolbar = angular.module( 'toolbarControllers', [] )

toolbar.controller( 'ToolbarController', [ '$scope', '$http', '$state', function( $scope, $http, $state ) {
    console.log( 'Toolbar controller' ) // this works if navigation doesn't works

    // how can I tell customerControllers what to do now on certain events, like filtering of data?
} ] )

navigation.js

var navigation = angular.module( 'navigationControllers', [] )

navigation.controller( 'NavigationController', [ '$scope', '$http', '$state', function( $scope, $http, $state ) {
    console.log('Navigation controller called!') // this works

    // get the data
} ] )

Everything is still quite barebones, because I'm just trying to set up the basic interaction between the views before proceeding.

Currently, with the code above, only the navigation works while the other two views are ignored. If I remove the code in routes.config() and parent: "default", the other two views seem to work instead. Something doesn't quite work with the inheritance here.

  • How can I get all three views to work at the same time? (with navigation always being there regardless of the content)
  • What's the best way to get the toolbar to interact with the content (in this case, customerControllers) while still being an independent module? (less important, my main issue is the first problem)

Edit: After further testing I came to the conclusion that somehow, the parent state overwrites the child states' settings. It's very weird: If I remove parent: 'default' and just configure everything in one place, it works. AS soon as I add parent: 'default' it starts failing, since the parent's configuration takes precedence over the child configuration... but shouldn't it be the exact opposite? Also, it's not really a solution, since I'm trying to write my modules independent from each other.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.