javascriptangularjsangular-ui-routernested-views

Angular UI-Router : URL changed but view isn't loaded


I'm working on my UI-Router app with nested views. I defined some states like this:

 $stateProvider

    .state('parent', {
      url: "/parent",
       views: {
         'area1': {templateUrl : 'parentView.html'},
         'area2' : ... // some other areas + template
       }
    })

    .state('parent.child1', {
      url: "/child1",
       views: {
          'area1' : {templateUrl : 'child1View.html'},
          'area2' : ...  // still some other areas, not changing 
       }
    })

    .state('parent.child2', {
      url: "/child2",
       views: {
          'area1' : {templateUrl : 'child2View.html'},
          'area2' : ...  // still some other areas, not changing 
       }
    })

When using the app, I have a main view divided into some areas. In the 1st area, I use a specific html file. If I click on a link, the app goes to a child state using $state.go('myState'). At that time, the URL is changed but the child view isn't loaded in the page.

I searched for answers in the site, and I found this question from another one who seems to encounter the same problem here : Angular Router - Url changes but view does not load

Do you know what I missed?

Sorry for bad English


Solution

  • There is a working plunker

    Most likely the index.html contains these targets:

    <body>
        <div ui-view="area1"></div>
        <div ui-view="area2"></div>
        ...
    

    So, if both, parent and child do target these, we need to use absolute naming:

    .state('parent.child1', {
      url: "/child1",
       views: {
          'area1@' : {template : '<h2>child 1 area 1 </h2>'},
          'area2@' : {template : '<h2>child 1 area 2</h2>'},
       }
    })
    
    .state('parent.child2', {
      url: "/child2",
       views: {
          'area1@' : {template : '<h2>child 2 area 1 </h2>'},
          'area2@' : {template : '<h2>child 2 area 2</h2>'},
       }
    })
    

    Let's observe doc:

    View Names - Relative vs. Absolute Names

    Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname@statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.

    For example, the previous example could also be written as:

    .state('report',{
        views: {
          'filters@': { },
          'tabledata@': { },
          'graph@': { }
        }
    })
    

    So, our child needs to use 1) view target Name 2) delimiter @ and 3) the state name (in our string empty representing the root): 'area1@'

    These links, similar to $state.go() will work now:

      <a ui-sref="parent">
      <a ui-sref="parent.child1">
      <a ui-sref="parent.child2">
    

    Check it here