简体   繁体   中英

Angular UI Router multiple/named routes

I have a user layout file that is the template for any user pages:

<div class="user-wrapper">
    <div ui-view="menu"></div>
    <div ui-view="content"></div>
</div>

Depending on the state I want the menu to be different. Such as:

    .state('user', {
        url: '/user',
        templateUrl: 'partials/user.html',
        controller: 'userController',
    })

    .state('user.one', {
        url: '/one',
        controller: 'oneController',
        views: {
            "menu": { templateUrl: "partials/client-menu.html" },
            "content": { templateUrl: "partials/one.html" }
        },
    });

    .state('user.two', {
        url: '/two',
        controller: 'twoController',
        views: {
            "menu": { templateUrl: "partials/client-menu.html" },
            "content": { templateUrl: "partials/two.html" }
        },
    });

    .state('user.three', {
        url: '/three',
        controller: 'threeController',
        views: {
            "menu": { templateUrl: "partials/admin-menu.html" },
            "content": { templateUrl: "partials/three.html" }
        },
    });

Now you can see "one" and "two" both use the same menu but "three" uses a different menu. This all works fine but is there a way to avoid duplicating the menu on "one" and "two".

Such as making a "user.client" state that uses the "user-menu.html" then "one" would be "user.client.one" instead and only have to specify the content.

I think the main problem is the

<div ui-view="content"></div>

is on the grandfather of the "user.client.one" so how can it specify the content?

I would say, that the trick is to move the "menu" view definition into parent state "user"

.state('user', {
    url: '/user',
    views: {
      "" : {
        templateUrl: 'partials/user.html',
        controller: 'userController',
      },
      "menu@user": { templateUrl: "partials/client-menu.html" },
     },
     ...

So, what happened? any child state of the "user" will already have the content of the "menu" filled, with the default templateUrl: "partials/client-menu.html"

Any other child, can override that...

.state('user.one', {
    url: '/one',
    controller: 'oneController',
    views: {
        // "menu": already set by parent
        "content": { templateUrl: "partials/one.html" }
     ....

.state('user.two', {
    url: '/two',
    views: {
        // "menu": set in parent
        "content": { templateUrl: "partials/two.html" }
        ...

.state('user.three', {
    url: '/three',
    controller: 'threeController',
    views: {
        // here we override that
        "menu": { templateUrl: "partials/admin-menu.html" },
        "content": { templateUrl: "partials/three.html" }
    ...

Maybe, check this Q & A for some more ideas about multi view nesting:

I think a found a solution user the @ for absolute views:

.state('user', {
    url: '/user',
    templateUrl: 'partials/user.html',
    controller: 'userController',
})

.state('user.client', {
    url: '/client',
    views: {
        "menu": { templateUrl: "partials/client-menu.html" }
    },
})

.state('user.admin', {
    url: '/admin',
    views: {
        "menu": { templateUrl: "partials/admin-menu.html" }
    },
})

.state('user.client.one', {
    url: '/one',
    controller: 'oneController',
    views: {
        "content@user": { templateUrl: "partials/one.html" }
    },
});

.state('user.client.two', {
    url: '/two',
    controller: 'twoController',
    views: {
        "content@user": { templateUrl: "partials/two.html" }
    },
});

.state('user.admin.three', {
    url: '/three',
    controller: 'threeController',
    views: {
        "content@user": { templateUrl: "partials/three.html" }
    },
});

It feels abit cleaner but I'm not sure if its the right approach still.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM