Angular UI-Router Multiple Named Views

Desired behavior

I am using AngularJS and Angular UI-Router.

  • I want to allow two child states to share the parent state.
  • I want the child states to populate ui-view

    in the parent state view with their own view.
  • I want one of the two child states to have three ui-view

    in its view, each populated with views.

Attempted diagram:

Parent: <ui-view>
        filled by
          Child:  <ui-view> <ui-view> <ui-view>
                    filled    filled   filled

      

Specific details of my situation

I have a state named category-details

. Inside the view for this abstract state, I have an unnamed one ui-view

. In one of two child states ( category-details.selected

), I want to use multiple named views .

Current work strategy

Here is an abstract state. Very basic, but included for your reference.

.state('category-details', {
    abstract: true,
    data: {
        pageTitle: 'Category Details'
    },
    templateUrl: "views/category-details.html",
})

      

In state category-details.selected

(state that will have multiple named views), I set unnamed ui-view

from category-details.html

in category-details-selected.html

:

.state('category-details.selected', {
    views: {
        '': {
            templateUrl: 'views/category-details-selected.html',
            controller: 'CategoryDetailsSelectedCtrl'
        }
    }
})

      

Inside the view category-details-selected.html

, I have three names ui-views

:

<div ui-view="firstNamedView"></div>
<div ui-view="secondNamedView"></div>
<div ui-view="thirdNamedView"></div>

      

Finally, I define a state to set these three ui-view

to satisfy the third part of my desired behavior:

.state('category-details.selected.aspect', {
    url:"/category-details/:selectedCategory",
    views: {
        'firstNamedView': {
            templateUrl: 'views/first-named-view.html',
            controller: 'FirstNamedViewCtrl'
        },
        'secondNamedView': {
            templateUrl: 'views/second-named-view.html',
            controller: 'SecondNamedViewCtrl'
        },
        'thirdNamedView': {
            templateUrl: 'views/third-named-view.html',
            controller: 'ThirdNamedViewCtrl'
        }
    }
});

      

Why is my solution inconvenient and suboptimal

Adding state category-details.selected.aspect

to set persistent items (three ui-view

's) in the view is category-details-selected

not required. This forces additional state to be created every time I need multiple named views.

What i tried

I believe I need to move the url and state views category-details.selected.aspect

to the component of views

my parent state ( category-details.selected

). It will look like this:

.state('category-details.selected', {
    url:"/category-details/:selectedCategory",
    views: {
        '': {
            templateUrl: 'views/category-details-selected.html',
            controller: 'CategoryDetailsSelectedCtrl'
        },
        'firstNamedView': {
            templateUrl: 'views/first-named-view.html',
            controller: 'FirstNamedViewCtrl'
        },
        'secondNamedView': {
            templateUrl: 'views/second-named-view.html',
            controller: 'SecondNamedViewCtrl'
        },
        'thirdNamedView': {
            templateUrl: 'views/third-named-view.html',
            controller: 'ThirdNamedViewCtrl'
        }
    }
})

      

This resulted in the unnamed ui-view

being set correctly, but three names ui-view

were not filled in.

Since choosing the three named ui-view

was a problem, I then tried to select them using the ones absolute selectors

described here . This didn't fix the problem. I tried:

firstNamedView
firstNamedView@
firstNamedView@category-details.selected
(others of course)

      

Concluding remarks

Is what I imagine possible, is another way better, or is my current method better? It boils down to assigning a child to a ui-view

parent ui-view

set at the same time. I thought the last sentence was too confusing on its own, so I included the whole example.

Please let me know if I can provide more clarifications such as versions. Thank.

+3


source to share


1 answer


Abstract states need their own <ui-view/>

for their children to connect.

The state of the parent state category-details

is a state abstract

. The child state requires some reference u-view to connect that state. In yours, I believe the view /category-details.html

does not have any ui-view (as you mentioned, what category-details-selected.html

ui-view contains).

Try the following:

.state('category-details', {
  abstract: true,
  data: {
    pageTitle: 'Category Details'
  },
  templateUrl: "views/category-details-selected.html",
})

.state('category-details.selected', {
  url:"/category-details/:selectedCategory",
  views: {       
    'firstNamedView': {
        templateUrl: 'views/first-named-view.html',
        controller: 'FirstNamedViewCtrl'
    },
    'secondNamedView': {
        templateUrl: 'views/second-named-view.html',
        controller: 'SecondNamedViewCtrl'
    },
    'thirdNamedView': {
        templateUrl: 'views/third-named-view.html',
        controller: 'ThirdNamedViewCtrl'
    }
  }
})

      

Here we give an abstract view of the template, which has a ui-view, to fill the child.

Check out the documentation for ui-router: Abstract State for more information.


EDIT : I assumed it views/category-details.html

doesn't contain any ui-view. However, it was then pointed out that it views/views/category-details.html

has a ui-view



This is what works for me:

category-details.html:

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

      

category-details-selected.html:

<div ui-view="firstNamedView"></div>
<div ui-view="secondNamedView"></div>
<div ui-view="thirdNamedView"></div>

      

router:

    .state('category-details', {
        abstract: true,
        data: {
            pageTitle: 'Category Details'
        },
        templateUrl: "../app/atest/category-details.html",
    })


    .state('category-details.selected', {
        url: "/atest",
        views: {
            '': {
                templateUrl: "../app/atest/category-details-selected.html",
                //   controller: 'approvalsCtrl as vm',
            },
            'firstNamedView@category-details.selected': {
                templateUrl: '../app/atest/first.html',
                //    controller: 'approvalsCtrl as vm',
            },
            'secondNamedView@category-details.selected': {
                templateUrl: '../app/atest/second.html',
                //   controller: 'approvalsCtrl as vm',
            },
            'thirdNamedView@category-details.selected': {
                templateUrl: '../app/atest/third.html',
                //   controller: 'approvalsCtrl as vm',
            }
        }
    })

      

I could see you mentioned that you tried using it firstNamedView@category-details.selected

, but it didn't work for you. The above example works for me. Check if you have category-details.html

and category-details-selected.html

view2 → 2>.

+1


source







All Articles