ui router does not put the content in the named ui

2019-03-03 12:11发布

问题:

When I enter the route

\#\projects\100\dates\2014-01-01

in the url and press return I get the "projects" state.

I expected to trigger "projects.selected.dates" state.

Why does the routing not work? Actually it works locally on my machine without named view...

http://plnkr.co/edit/0DJ6W7QEPx2UzpdzDrVu?p=preview

'use strict';
angular
  .module('projectplanner', ['ui.router'])
  .config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/projects');
    $stateProvider
      .state('projects', {

        url: '/projects',
        views: {
          'menu': {
            template: 'Start your projects!'
          },
          'content': {
            templateUrl: "projects.html",
            controller: 'ProjectsController'
          }
        }
      })
      .state('projects.selected', {
        url: '/:projectId'
      })
      .state('projects.selected.dates', {
        url: '/dates/:date',
        views: {
          'menu': {
            templateUrl: 'menu.html'
          },
          'content': {
            templateUrl: 'dateplanner.html',
            controller: 'DateplannerController'
          }
        }
      })
  });

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

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title> 
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
 <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.20/angular.js" data-semver="1.2.20"></script>
  <script data-require="ui-router@*" data-semver="0.2.10" src="https://rawgit.com/angular-ui/ui-router/0.2.10/release/angular-ui-router.js"></script>

  <script src="app.js"></script>
  <script src="ProjectsController.js"></script> 
    <script src="DateplannerController.js"></script> 

</head>

<body>
  <div class="wrapper" >
    <header class="aside">Logo</header>
    <div ui-view="menu" id="menu" class="aside"></div>
    <div ui-view="content" class="main">
    </div>
  </div>
</body>

</html>

回答1:

There is the updated and working plunker, and this is the essential update:

  .state('projects.selected.dates', {
    url: '/dates/:date',
    views: {
      'menu@': {                     // HERE is @ added
        templateUrl: 'menu.html'
      },
      'content@': {                  // HERE is @ added
        templateUrl: 'dateplanner.html',
        controller: 'DateplannerController'
      }
    }
  })

See the '@' at the end of the ui-view name

The full explanation is here:

  • View Names - Relative vs. Absolute Names (cite)

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.

So, what I did is use of the absolute name .. targeting the root - index.html

Some examples from documentation... greatly explaining that all:

$stateProvider
  .state('contacts', {
    // This will get automatically plugged into the unnamed ui-view 
    // of the parent state template. Since this is a top level state, 
    // its parent state template is index.html.
    templateUrl: 'contacts.html'   
  })
  .state('contacts.detail', {
    views: {
        ////////////////////////////////////
        // Relative Targeting             //
        // Targets parent state ui-view's //
        ////////////////////////////////////

        // Relatively targets the 'detail' view in this state's parent state, 'contacts'.
        // <div ui-view='detail'/> within contacts.html
        "detail" : { },            

        // Relatively targets the unnamed view in this state's parent state, 'contacts'.
        // <div ui-view/> within contacts.html
        "" : { }, 

        ///////////////////////////////////////////////////////
        // Absolute Targeting using '@'                      //
        // Targets any view within this state or an ancestor //
        ///////////////////////////////////////////////////////

        // Absolutely targets the 'info' view in this state, 'contacts.detail'.
        // <div ui-view='info'/> within contacts.detail.html
        "info@contacts.detail" : { }

        // Absolutely targets the 'detail' view in the 'contacts' state.
        // <div ui-view='detail'/> within contacts.html
        "detail@contacts" : { }

        // Absolutely targets the unnamed view in parent 'contacts' state.
        // <div ui-view/> within contacts.html
        "@contacts" : { }