0

任何解释为什么 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) {

谢谢

<!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>
4

2 回答 2

0

ui-router doesn't fully support this. You may check this library for nested routing: http://angular-route-segment.com

It provides the functionality for creating tree-like routing hierarchy which can be changed without losing the state.

$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});
于 2013-08-14T19:01:20.690 回答
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();
}],
于 2014-01-23T18:17:42.380 回答