NSS
NSS

Reputation: 2022

Angular UI-Router Multiple Menu (Top Horizontal and Left Vertical Menu)

I have top level menu, and then I have left menus, which will be refreshed based on the selected top level menu. I am able to create that link, but as soon as I select the left menu, it goes blank as can be seen when selecting HOME. At this time only HOME is wired up Route1 & Route2 is not wired up.

Also here is the Plunker for it http://plnkr.co/edit/Jwow4VtNsSfMMcpv6qaa?p=preview

How do I prevent resetting/reloading of left menu on selection? I also want to keep highlighted the clicked left menu.

<!DOCTYPE html>
<html ng-app="myapp">

<head>
    <title>AngularJS: UI-Router Quick Start</title>
    <!-- Bootstrap CSS -->
    <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>

<body class="container">

    <div class="navbar">
        <div class="navbar-inner">
            <a class="brand" ui-sref="index">Quick Start</a>
            <ul class="nav">
                <li><a ui-sref="index">Home</a></li>
                <li><a ui-sref="route1">Route 1</a></li>
                <li><a ui-sref="route2">Route 2</a></li>
            </ul>
        </div>
    </div>

    <div class="row">
        <div class="span6">
            <div class="well" ui-view="LeftMenu"></div>
        </div>
        <div class="span6">
            <div class="well" ui-view="Content"></div>
        </div>
    </div>

    <!-- Angular -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
    <!-- UI-Router -->
    <script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>

    <!-- App Script -->
    <script>
    var myapp = angular.module('myapp', ["ui.router"])
    myapp.config(function($stateProvider){
        $stateProvider
            .state('index', {
                url: "",
                views: {
                    "LeftMenu": {
                        template: '<ul><li><a ui-sref="LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
                    },
                    "Content": {
                        template: "LeftMenu index selected"
                    }
                }
            })
             .state('LeftMenuMenu1', {
                 views:{
                 "Content": {
                     template: "LeftMenu.Menu1 selected"
                 }
             }
        })
        .state('LeftMenuMenu2', {
             views: {
                 "Content": {
                     template: "LeftMenu.Menu2 selected"
                 }
             }
         })
         .state('LeftMenuMenu3', {
             url: "",
             views: {
                 "Content": {
                     template: "LeftMenu.Menu3 selected"
                 }
             }
         })
        .state('route1', {
            url: "/route1",
            views: {
                "LeftMenu": {
                    template: '<ul><li><a ui-sref="Route1.Menu1">Route1-Left Menu1</a></li><li><a ui-sref="Route1.Menu2">Route1-Left Menu2</a></li><li><a ui-sref="Route1.Menu3">Route1-Left Menu3</a></li></ul>'
                },
                "viewB": {
                    template: "route1.viewB"
                }
            }
        })
        .state('route2', {
            url: "/route2",
            views: {
                "LeftMenu": {
                    template:'<ul><li><a href="">Route2-Left Menu1</a></li><li><a href="">Route2-Left Menu2</a></li><li><a href="">Route2-Left Menu3</a></li></ul>'
                },
                "viewB": {
                    template: "route2.viewB"
                }
            }
        })
    });
    </script>

</body>

</html>

Upvotes: 1

Views: 1476

Answers (1)

cbass
cbass

Reputation: 2558

I think what you would want to do is to work with substates, rather than only root states. In each root state you are then able to set the left menu options.

Consider the below example where index is the root state where we set the left menu and set where we want the sub states to be rendered in the view. Each substate(index.LeftMenuMenu1, index.LeftMenuMenu2, index.LeftMenuMenu3), will then be rendered where ever we placed the <div ui-view=content></div> element.

$stateProvider
    //Root state
    .state('index', {
        url: "",
        views: {
            //Set left side bar
            "LeftMenu": {
                template: '<ul><li><a ui-sref="index.LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="index.LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="index.LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
            },
            //Each substate will live here
            "Content": {
                template: "<div ui-view></div>"
            }
        }
    })
    //substates
    .state('index.LeftMenuMenu1', {
        template: "LeftMenu.Menu1 selected"
    })
    .state('index.LeftMenuMenu2', {
        template: "LeftMenu.Menu2 selected"
    })
    .state('index.LeftMenuMenu3', {
        template: "LeftMenu.Menu3 selected"
    })

Then you reuse this pattern for the other sections on your page.

$stateProvider
    ...
    //Root state route 1
    .state('route1', {
        url: "/route1",
        views: {
            "LeftMenu": {
                template: 'Route 1 menu options..'
            },
            "Content": {
                template: "<div ui-view></div>"
            }
        }
    })
    .state('route1.LeftMenuMenu1', {
        template: "LeftMenu.Menu1 selected"
    })
    .state('route1.LeftMenuMenu2', {
        template: "LeftMenu.Menu2 selected"
    })
    //Root state route 2
    .state('route2', {
        url: "/route2",
        views: {
            "LeftMenu": {
                template: 'Route 2 menu options..'
            },
            "Content": {
                template: "<div ui-view></div>"
            }
        }
    })
    .state('route2.LeftMenuMenu1', {
        template: "LeftMenu.Menu1 selected"
    })
    .state('route2.LeftMenuMenu2', {
        template: "LeftMenu.Menu2 selected"
    })

Updated plunker

However, is your case with the left menu is that you will only change the links and the view will be the same, I would recommend to user another pattern. Probably having a menu service that servers the menu options. And the for each root state you can use the onEnter property to trigger the menu options to update.

Upvotes: 2

Related Questions