With multiple views my child template is not loading, in Angular UI when URL changes

和自甴很熟 提交于 2019-12-11 12:16:39

问题


I've seen a few questions like this, so forgive me if I've overlooked a crucial detail from them.

When I load http://localhost:8000/characters/#/mages/detail/3 I get redirected to my 'otherwise' url: $urlRouterProvider.otherwise("/users");

But my state provider (if I've understood this correctly) should load the correct page:

  $stateProvider
    .state('users', {
      url: "/users",
      templateUrl: DjangoProperties.STATIC_URL + "partials/users.html"
    })
    .state('users.list', {
      url: "/list",
      templateUrl: DjangoProperties.STATIC_URL +  "partials/users.list.html",
      controller: 'UserListCtrl'
    })
    .state('users.detail', {
      url: "/detail/{userID:int}",
      templateUrl: DjangoProperties.STATIC_URL +  "partials/users.detail.html",
      controller: 'UserDetailCtrl'
    })
    .state('mages', {
      url: "/mages",
      templateUrl: DjangoProperties.STATIC_URL + "partials/mages.html"
    })
    .state('mages.list', {
      url: "/list",
      templateUrl: DjangoProperties.STATIC_URL + "partials/mages.list.html",
      controller: 'MageCtrl'
    })
    .state('mages.detail', {
         url: "/detail/{mageID:int}",
         views:{
            "@mage.detail": {
                templateUrl: DjangoProperties.STATIC_URL +  "partials/mages.detail.html",
                controller: 'MageCtrl',
            },
            "characteristics@mage.detail": {
                templateUrl: DjangoProperties.STATIC_URL +  "common_partials/characteristics.html"
            }, 
            "attributes@mage.detail": {
                templateUrl: DjangoProperties.STATIC_URL +  "common_partials/attributes.html"
            }, 
            "skills@mage.detail": {
                templateUrl: DjangoProperties.STATIC_URL +  "common_partials/skills.html"
            }, 
            "spells@mage.detail": {
                templateUrl: DjangoProperties.STATIC_URL +  "partials/spells.html"
            }, 
        }
    });
  }]);

Here is my mages.html:

<h1>Mages</h1>
<hr/>
<a ui-sref="mages.list">Show List</a>
<div ui-view></div>

and my mages.detail.html

<h4>{{mage.name}}</h4>
<div ui-view>
  <div ui-view="characteristics"></div>
  <div ui-view="attributes"></div>
  <div ui-view="skills"></div>
  <div ui-view="spells"></div>
</div>

None of these are loaded, just the default 'list' page.

I feel I've gotten muddled over my view names, but I can't figure out what to do to fix them?


回答1:


There is another working plunker

In case we want to have only two levels

  • mages
  • mages.list
  • mages.deatil

We have to adjust the state def like this:

.state('mages', {
  url: "/mages",
  templateUrl: DjangoProperties.STATIC_URL + "partials/mages.html"
})
.state('mages.list', {
  url: "/list",
  templateUrl: DjangoProperties.STATIC_URL + "partials/mages.list.html",
  controller: 'MageCtrl'
})
.state('mages.detail', {
     url: "/detail/{mageID:int}",
     views:{

        "": {
            templateUrl: DjangoProperties.STATIC_URL +  "partials/mages.detail.html",
            controller: 'MageCtrl',
        },
        "state@mages.detail" : {
          templateUrl: "tpl.html",
        },
        "characteristics@mages.detail": {
            //templateUrl: DjangoProperties.STATIC_URL +  "common_partials/characteristics.html"
            template: "common_partials/characteristics.html",
        }, 
        "attributes@mages.detail": {
            //templateUrl: DjangoProperties.STATIC_URL +  "common_partials/attributes.html"
            template: "common_partials/attributes.html"
        }, 
        "skills@mages.detail": {
            //templateUrl: DjangoProperties.STATIC_URL +  "common_partials/skills.html"
            template: "common_partials/skills.html"
        }, 
        "spells@mages.detail": {
            //templateUrl: DjangoProperties.STATIC_URL +  "partials/spells.html"
            template: "partials/spells.html"
        }, 
    }
});

And the mages.list.html will be now like this (no place for child detail)

<h3>The mages list</h3>
<h4>{{mage.name}}</h4>

<li><a href="#/mages/detail/1">mages/detail/1</a>
<li><a href="#/mages/detail/2">mages/detail/2</a>
<li><a href="#/mages/detail/3">mages/detail/3</a>
<li><a href="#/mages/detail/4">mages/detail/4</a>

And the mages.detail.html wil be:

<div >

  <a ui-sref="mages.list">back to list</a>

  <div ui-view="state"></div>
  <div ui-view="characteristics"></div>
  <div ui-view="attributes"></div>
  <div ui-view="skills"></div>
  <div ui-view="spells"></div>
</div>

check it here




回答2:


I tried to adjust your settings, and show you one possible way.

There is a working plunker

So, these would be new states mages:

.state('mages', {
  url: "/mages",
  templateUrl: DjangoProperties.STATIC_URL + "partials/mages.html"
})
.state('mages.list', {
  url: "/list",
  templateUrl: DjangoProperties.STATIC_URL + "partials/mages.list.html",
  controller: 'MageCtrl'
})

where detail is child of the list

.state('mages.list.detail', {
     url: "/detail/{mageID:int}",
     views:{
       /*
        "@mage.detail": {
            templateUrl: DjangoProperties.STATIC_URL +  "partials/mages.detail.html",
            controller: 'MageCtrl',
        },
        */
        "" : {
          templateUrl: "tpl.html",
        },
        "characteristics@mages.list": {
            //templateUrl: DjangoProperties.STATIC_URL +  "common_partials/characteristics.html"
            template: "common_partials/characteristics.html",
        }, 
        "attributes": {
            //templateUrl: DjangoProperties.STATIC_URL +  "common_partials/attributes.html"
            template: "common_partials/attributes.html"
        }, 
        "skills": {
            //templateUrl: DjangoProperties.STATIC_URL +  "common_partials/skills.html"
            template: "common_partials/skills.html"
        }, 
        "spells": {
            //templateUrl: DjangoProperties.STATIC_URL +  "partials/spells.html"
            template: "partials/spells.html"
        }, 
    }
});

And these are two basic tmplates

mages.html (as it was, no change):

<h1>Mages</h1>
<hr/>
<a ui-sref="mages.list">Show List</a>
<div ui-view></div>

The mages.list.html

<h3>The mages list</h3>
<h4>{{mage.name}}</h4>

<li><a href="#/mages/list/detail/1">mages/list/detail/1</a>
<li><a href="#/mages/list/detail/2">mages/list/detail/2</a>
<li><a href="#/mages/list/detail/3">mages/list/detail/3</a>
<li><a href="#/mages/list/detail/4">mages/list/detail/4</a>

<hr /> 

<div >
  <div ui-view=""></div>
  <div ui-view="characteristics"></div>
  <div ui-view="attributes"></div>
  <div ui-view="skills"></div>
  <div ui-view="spells"></div>
</div>

It is now containing the links to detail and also contains the anchor for detail views




回答3:


I would like to show how the view naming is working. There is a working plunker

So, let's have this index.html:

<H1><ui-view name="title" /></H1>

<ul>
  <li><a ui-sref="parent">parent</a>
  <li><a ui-sref="parent.child">parent.child</a>
</ul>

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

There is one unnamed view, and one named (title). We have two states. and both will be targeting this 'title' view:

  .state('parent', {
      ...
      views : {
        ...
        "title" : {
          template : "parent is setting title inside of index.html"
        }
      }
  })
  .state('parent.child', { 
      ...
      views : {
        ...
        "title@" : {
          template : "CHILD is setting title inside of index.html"
        },
      }              
  })

What we can see, is that parent calls the view "title" (relative name). The reason is, that index.html (root view) is its parent. The absolute name would work as well (and in fact is created behind the scene): "title@"

On the other hand, child must use absolute naming, because it targets view which is not part of the parent... it is grand-parent (root). So the view name is: "title@"

Now, child template, injected into parent is:

<div>

  <h4>Child</h4>

  <hr />

  View A:
  <div ui-view="viewA" ></div>
  View B:
  <div ui-view="viewB" ></div>

</div>

and that means that child state definition now will be:

 .state('parent.child', { 
      ...
      views : {
        "" : {
          templateUrl: 'tpl.child.html',
          controller: 'ChildCtrl',
        },            
        "viewA@parent.child" : {
          template : "<h5>child content of the view A</h5>"
        },
        "viewB@parent.child" : {
          template : "<h5>child content of the view B</h5>"
        }
        ... // title into the root
      }          
 })

So firstly we injected child template into parent unnamed view "": {...

And next we inject some views (existing inside of this child) with absolute naming === using the child full state name "viewB@parent.child"

Check it in action here

Documentation:

Multiple Named Views

...

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.



来源:https://stackoverflow.com/questions/28749378/with-multiple-views-my-child-template-is-not-loading-in-angular-ui-when-url-cha

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!