AngularJS嵌套路由示例问题

时间:2013-06-24 07:55:21

标签: angularjs angularjs-routing

为angular-ui-router(https://github.com/angular-ui/ui-router)的示例代码(ui-router / sample / index.html)看起来像这样的任何解释。具体做法是:

  1. 为什么嵌套的对象定义如控制器?
  2. 为什么依赖的规范如下:

    angular.module('sample',['ui.compat'])   的.config(     ['$ stateProvider','$ routeProvider','$ urlRouterProvider',     function($ stateProvider,$ routeProvider,$ urlRouterProvider){

  3. 感谢

    <!doctype html>
    <html lang="en" ng-app="sample"><head>
      <meta charset="utf-8">
      <link rel="stylesheet" type="text/css" href="bootstrap.min.css">
      <style type="text/css">
        .fade-enter-setup, .fade-leave-setup {
          transition: opacity 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0s;
        }
        .fade-enter-setup,
        .fade-leave-setup.fade-leave-start {
          opacity: 0;
        }
        .fade-leave-setup,
        .fade-enter-setup.fade-enter-start {
          opacity: 1;
        }
      </style>
      <script src="../lib/angular-1.1.4.js"></script>
      <script src="../build/angular-ui-router.js"></script>
    
      <!-- could easily use a custom property of the state here instead of 'name' -->
      <title ng-bind="$state.current.name + ' - ui-router'">ui-router</title>
    </head><body>
    <div class="navbar navbar-fixed-top">
      <div class="navbar-inner"><div class="container">
        <a class="brand" href="#">ui-router</a>
        <ul class="nav">
          <li ng-class="{ active: $state.includes('contacts') }"><a href="#/contacts">Contacts</a></li>
          <li ng-class="{ active: $state.includes('about') }"><a href="#/about">About</a></li>
        </ul>
        <p class="navbar-text pull-right" ui-view="hint"></p>
      </div></div>
    </div>
    <div class="container" style="margin-top:60px" ui-view ng-animate="{enter:'fade-enter'}"></div>
    <hr>
    <pre>
      $state = {{$state.current.name}}
      $stateParams = {{$stateParams}}
    </pre>
    </body><script>
    
    function findById(a, id) {
      for (var i=0; i<a.length; i++) {
        if (a[i].id == id) return a[i];
      }
    }
    
    angular.module('sample', ['ui.compat'])
      .config(
        [        '$stateProvider', '$routeProvider', '$urlRouterProvider',
        function ($stateProvider,   $routeProvider,   $urlRouterProvider) {
          $urlRouterProvider
            .when('/c?id', '/contacts/:id')
            .otherwise('/');
    
          $routeProvider
            .when('/user/:id', {
              redirectTo: '/contacts/:id',
            })
            .when('/', {
              template: '<p class="lead">Welcome to the ngStates sample</p><p>Use the menu above to navigate</p>' +
                '<p>Look at <a href="#/c?id=1">Alice</a> or <a href="#/user/42">Bob</a> to see a URL with a redirect in action.</p>',
            });
    
          $stateProvider
            .state('contacts', {
              url: '/contacts',
              abstract: true,
              templateUrl: 'contacts.html',
              controller:
                [        '$scope', '$state',
                function ($scope,   $state) {
                  $scope.contacts = [{
                    id: 1,
                    name: "Alice",
                    items: [{
                      id: 'a',
                      type: 'phone number',
                      value: '555-1234-1234',
                    },{
                      id: 'b',
                      type: 'email',
                      value: 'alice@mailinator.com',
                    }],
                  }, {
                    id: 42,
                    name: "Bob",
                    items: [{
                      id: 'a',
                      type: 'blog',
                      value: 'http://bob.blogger.com',
                    },{
                      id: 'b',
                      type: 'fax',
                      value: '555-999-9999',
                    }],
                  }, {
                    id: 123,
                    name: "Eve",
                    items: [{
                      id: 'a',
                      type: 'full name',
                      value: 'Eve Adamsdottir',
                    }],
                  }];
    
                  $scope.goToRandom = function () {
                    var contacts = $scope.contacts, id;
                    do {
                      id = contacts[Math.floor(contacts.length * Math.random())].id;
                    } while (id == $state.params.contactId);
                    $state.transitionTo('contacts.detail', { contactId: id });
                  };
                }],
            })
            .state('contacts.list', {
              // parent: 'contacts',
              url: '',
              templateUrl: 'contacts.list.html',
            })
            .state('contacts.detail', {
              // parent: 'contacts',
              url: '/{contactId}',
              resolve: {
                something:
                  [        '$timeout', '$stateParams',
                  function ($timeout,   $stateParams) {
                    return $timeout(function () { return "Asynchronously resolved data (" + $stateParams.contactId + ")" }, 10);
                  }],
              },
              views: {
                '': {
                  templateUrl: 'contacts.detail.html',
                  controller:
                    [        '$scope', '$stateParams', 'something',
                    function ($scope,   $stateParams,   something) {
                      $scope.something = something;
                      $scope.contact = findById($scope.contacts, $stateParams.contactId);
                    }],
                },
                'hint@': {
                  template: 'This is contacts.detail populating the view "hint@"',
                },
                'menu': {
                  templateProvider:
                    [ '$stateParams',
                    function ($stateParams){
                      // This is just to demonstrate that $stateParams injection works for templateProvider
                      // $stateParams are the parameters for the new state we're transitioning to, even
                      // though the global '$stateParams' has not been updated yet.
                      return '<hr><small class="muted">Contact ID: ' + $stateParams.contactId + '</small>';
                    }],
                },
              },
            })
            .state('contacts.detail.item', {
              // parent: 'contacts.detail',
              url: '/item/:itemId',
              views: {
                '': {
                  templateUrl: 'contacts.detail.item.html',
                  controller:
                    [        '$scope', '$stateParams', '$state',
                    function ($scope,   $stateParams,   $state) {
                      $scope.item = findById($scope.contact.items, $stateParams.itemId);
                      $scope.edit = function () {
                        $state.transitionTo('contacts.detail.item.edit', $stateParams);
                      };
                    }],
                },
                'hint@': {
                  template: 'Overriding the view "hint@"',
                },
              },
            })
            .state('contacts.detail.item.edit', {
              views: {
                '@contacts.detail': {
                  templateUrl: 'contacts.detail.item.edit.html',
                  controller:
                    [        '$scope', '$stateParams', '$state',
                    function ($scope,   $stateParams,   $state) {
                      $scope.item = findById($scope.contact.items, $stateParams.itemId);
                      $scope.done = function () {
                        $state.transitionTo('contacts.detail.item', $stateParams);
                      };
                    }],
                },
              },
            })
            .state('about', {
              url: '/about',
              templateProvider:
                [        '$timeout',
                function ($timeout) {
                  return $timeout(function () { return "Hello world" }, 100);
                }],
            })
            .state('empty', {
              url: '/empty',
              templateUrl: 'empty.html',
              controller:
                [        '$scope', '$state',
                function ($scope,   $state) {
                  // Using an object to access it via ng-model from child scope
                  $scope.data = {
                    initialViewTitle: "I am an initial view"
                  }
                  $scope.changeInitialViewTitle = function($event) {
                    $state.transitionTo('empty.emptycontent');
                  };
                  $scope.showInitialView = function($event) {
                    $state.transitionTo('empty');
                  };
              }]
            })
            .state('empty.emptycontent', {
              url: '/content',
              views: {
                'emptycontent': {
                  templateUrl: 'empty.content.html'
                }
              }
            });
        }])
        .run(
          [        '$rootScope', '$state', '$stateParams',
          function ($rootScope,   $state,   $stateParams) {
            $rootScope.$state = $state;
            $rootScope.$stateParams = $stateParams;
          }]);
    </script></html>
    

2 个答案:

答案 0 :(得分:0)

ui-router并不完全支持这一点。您可以检查此库以获取嵌套路由:http://angular-route-segment.com

它提供了创建树状路由层次结构的功能,可以在不丢失状态的情况下进行更改。

$routeSegmentProvider.

when('/section1',          's1.home').
when('/section1/prefs',    's1.prefs').
when('/section1/:id',      's1.itemInfo.overview').
when('/section1/:id/edit', 's1.itemInfo.edit').
when('/section2',          's2').

segment('s1', {
    templateUrl: 'templates/section1.html',
    controller: MainCtrl}).

within().

    segment('home', {
        templateUrl: 'templates/section1/home.html'}).

    segment('itemInfo', {
        templateUrl: 'templates/section1/item.html',
        controller: Section1ItemCtrl,
        dependencies: ['id']}).

    within().

        segment('overview', {
            templateUrl: 'templates/section1/item/overview.html'}).

        segment('edit', {
             templateUrl: 'templates/section1/item/edit.html'}).

        up().

    segment('prefs', {
        templateUrl: 'templates/section1/prefs.html'}).

    up().

segment('s2', {
    templateUrl: 'templates/section2.html',
    controller: MainCtrl});

答案 1 :(得分:0)

嵌套只是做这个例子的一种方式。你可以写

                'navTitle@': {
                templateUrl : 'pages/mypage.html',
                controller: 'myController',
            },

然后只需在应用中的任何其他位置定义myController。

function myController ($scope) {

};

就依赖性问题而言...这是以角度注入依赖项的一种方式,因此您可以在其他地方重用代码。

    .factory('appLoading', function($rootScope, $state) {
    return {
        loading : function() {
            $rootScope.status = 'loading';
            if(!$rootScope.$$phase) $rootScope.$apply();
        },
        ready : function(delay) {
            function ready() {
        $rootScope.status = 'ready';
        $rootScope.title = $state.current.data.title;
        if(!$rootScope.$$phase) $rootScope.$apply();

    }

}
};
})

然后,如果我想在一个模块中调用这个加载器,它将进入[]

喜欢在ui-router内的状态的onExit ...

    onExit: ['appLoading',
function ( appLoading) {
    appLoading.loading();
}],