2、Angular-Ui Router 嵌套状态和嵌套视图

317人阅读 评论(0) 收藏 举报
分类:


Methods for Nesting States
嵌套状态的方法

States can be nested within each other. There are several ways of nesting states:
状态可以相互嵌套,嵌套状态有几种方法:

  1. Using 'dot notation'. For example .state('contacts.list', {}).
    使用“点记法”。例如, .state('contacts.list', {})。
  2. Use the ui-router.stateHelper to build states from a nested state tree. Courtesy of @marklagendijk. 
    使用ui-router.stateHelper从嵌套状态树建立状态。感谢@marklagendijk的贡献。
  3. Using the parent property with the parent name as string. For example: parent: 'contacts'
    使用父属性与父名字符串。例如:parent: 'contacts'
  4. Using the parent property with the parent object. For example parent: contacts (where 'contacts' is a stateObject)
    使用父属性与父对象值一起使用。例如parent: contacts(“contacts”是一个状态对象)

Dot Notation
点记法

You can use dot syntax to infer your hierarchy to the $stateProvider. Below, contacts.listbecomes a child of contacts.
您可以使用点语法来推断您的$stateProvider层次结构。下面的contacts.list变成了contacts的子状态。

$stateProvider
  .state('contacts', {})
  .state('contacts.list', {});

stateHelper module
stateHelper模块

This is a 3rd party module created by @marklagendijk. So you have to include it in addition to ui-router. Visit the stateHelper repo to learn more
这是由@marklagendijk创建的第三方模块。所以你必须在ui-router之外加上它。访问stateHelper了解更多信息

angular.module('myApp', ['ui.router', 'ui.router.stateHelper'])
  .config(function(stateHelperProvider){
    stateHelperProvider.state({
      name: 'root',
      templateUrl: 'root.html',
      children: [
        {
          name: 'contacts',
          templateUrl: 'contacts.html',
          children: [
            {
              name: 'list',
              templateUrl: 'contacts.list.html'
            }
          ]
        },
        {
          name: 'products',
          templateUrl: 'products.html',
          children: [
            {
              name: 'list',
              templateUrl: 'products.list.html'
            }
          ]
        }
      ]
    });
  });

Parent Property using State Name String
使用状态名称的父属性

Alternately, you can specify the parent of a state via the parent property.
您可以通过父属性指定状态的父状态。

$stateProvider
  .state('contacts', {})
  .state('list', {
    parent: 'contacts'
  });

Object-based States
基于对象的状态

If you aren't fond of using string-based states, you can also use object-based states. The nameproperty goes in the object and the parent property must be set on all child states, like this:
如果您不喜欢使用基于字符串的状态,那么也可以使用基于对象的状态。name属性在对象中,父属性必须在所有子节点上设置,如下:

var contacts = { 
    name: 'contacts',
    templateUrl: 'contacts.html'
}
var contactsList = { 
    name: 'list',
    parent: contacts,
    templateUrl: 'contacts.list.html'
}

$stateProvider
  .state(contacts)
  .state(contactsList)

You can usually reference the object directly when using other methods and property comparisons:
在使用其他方法或属性比较时, 通常可以直接引用该对象:

$state.transitionTo(states.contacts);
$state.current === states.contacts;
$state.includes(states.contacts)

Registering States Order
注册状态顺序

You can register states in any order and across modules. You can register children before the parent state exists. It will queue them up and once the parent state is registered then the child will be registered.
您可以按任意顺序和跨模块注册状态。您可以在父状态存在之前注册子状态。它将对它们进行排队, 一旦注册了父状态, 就会注册该父状态的子状态。

Parent MUST Exist
父状态必须存在

If you register only a single state, like contacts.list, you MUST define a state called contacts at some point, or else no states will be registered. The state contacts.list will get queued until contacts is defined. You will not see any errors if you do this, so be careful that you define the parent in order for the child to get properly registered.
如果只注册单个状态 (如 "contacts.list"), 则必须在某个点定义一个称为 "contacts" 的状态, 否则将不注册任何状态。状态contacts.list将被排入队列, 直到定义了contacts状态。如果您没有定义contacts状态, 您将看不到任何错误, 因此请谨慎地定义父状态, 以便使子状态正确注册。

Naming Your States
命名您的状态

No two states can have the same name. When using dot notation the parent is inferred, but this doesn't change the name of the state. When explicitly providing a parent using the parentproperty, state names still must be unique. For example, you can't have two different states named "edit" even if they have different parents.

Nested States & Views
嵌套状态&视图

When the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well. Below, when the "contacts.list" state is active, the "contacts" state is implicitly active as well, because it's the parent state to "contacts.list".
当应用程序状态处于“活动状态”时,其所有的祖先状态也都是隐式的活动。下面,当“contacts.list”状态是活动的,“contacts”状态也是隐式活动的,因为它是“contacts.list”的父状态。

Child states will load their templates into their parent's ui-view.
子状态将把它们的模板加载到父视图中。

完整示例请参见: http://plnkr.co/edit/7FD5Wf?p=preview

$stateProvider
  .state('contacts', {
    templateUrl: 'contacts.html',
    controller: function($scope){
      $scope.contacts = [{ name: 'Alice' }, { name: 'Bob' }];
    }
  })
  .state('contacts.list', {
    templateUrl: 'contacts.list.html'
  });

function MainCtrl($state){
  $state.transitionTo('contacts.list');
}
<!-- index.html -->
<body ng-controller="MainCtrl">
  <div ui-view></div>
</body>
<!-- contacts.html -->
<h1>My Contacts</h1>
<div ui-view></div>
<!-- contacts.list.html -->
<ul>
  <li ng-repeat="contact in contacts">
    <a>{{contact.name}}</a>
  </li>
</ul>

What Do Child States Inherit From Parent States?
子状态从父状态那里继承了什么?

Child states DO inherit the following from parent states:
子状态从父状态继承以下内容:

Nothing else is inherited (no controllers, templates, url, etc). However, children of abstract states do inherit the url property of their parent as a prefix of their own url.
除此之外没有别的东西可继承 (包括控制器、模板、url 等)。然而, 抽象状态的子状态确实继承其父状态的 url 属性作为其自己的 url 的前缀。

Inherited Resolved Dependencies
继承的解析依赖关系

New in version 0.2.0

Child states will inherit resolved dependencies from parent state(s), which they can overwrite. You can then inject resolved dependencies into the controllers and resolve functions of child states.
子状态将从父状态(s)继承已解析的依赖项,它们可以覆盖这些依赖项。然后,您可以将解析的依赖项注入控制器,并解析子状态的函数。

$stateProvider.state('parent', {
      resolve:{
         resA:  function(){
            return {'value': 'A'};
         }
      },
      controller: function($scope, resA){
          $scope.resA = resA.value;
      }
   })
   .state('parent.child', {
      resolve:{
         resB: function(resA){
            return {'value': resA.value + 'B'};
         }
      },
      controller: function($scope, resA, resB){
          $scope.resA2 = resA.value;
          $scope.resB = resB.value;
      }

NOTE
注意
:

  • The resolve keyword MUST be relative to state not views (in case you use multiple views).
    解析关键字必须是相对于状态而不是视图(以防您使用多个视图)。
  • If you want a child resolve to wait for a parent resolve, you should inject the parent resolve keys into the child. (This behavior is different in ui-router 1.0).
    如果您希望一个子解析等待父解析,那么您应该将父解析注入到子解析中。(这种行为在ui-router 1.0中是不同的)。

Inherited Custom Data
继承自定义数据

Child states will inherit data properties from parent state(s), which they can overwrite.
子状态将从父状态继承数据属性, 子状态可以覆盖它们。

$stateProvider.state('parent', {
      data:{
         customData1:  "Hello",
         customData2:  "World!"
      }
   })
   .state('parent.child', {
      data:{
         // customData1 inherited from 'parent'
         // but we'll overwrite customData2
         customData2:  "UI-Router!"
      }
   });

$rootScope.$on('$stateChangeStart', function(event, toState){ 
    var greeting = toState.data.customData1 + " " + toState.data.customData2;
    console.log(greeting);

    // Would print "Hello World!" when 'parent' is activated
    // Would print "Hello UI-Router!" when 'parent.child' is activated
})

Scope Inheritance by View Hierarchy Only
仅按视图层次结构范围继承

Keep in mind that scope properties only inherit down the state chain if the views of your states are nested. Inheritance of scope properties has nothing to do with the nesting of your states and everything to do with the nesting of your views (templates).
请记住,如果您的状态的视图是嵌套的,那么范围属性只继承状态链。范围属性的继承与您的状态的嵌套无关,与您的视图的嵌套(模板)有关。

It is entirely possible that you have nested states whose templates populate ui-views at various non-nested locations within your site. In this scenario you cannot expect to access the scope variables of parent state views within the views of children states.
您可能有嵌套的状态,它们的模板在您的站点内的不同的非嵌套位置填充ui-view。在这个场景中,您不能期望在子状态视图中访问父状态视图的范围变量。

View Inherited Resolved Dependencies
视图继承已解析的依赖项

Views may inherit resolved dependencies from the state that they belong to, but may not inherit those of their sibling views.
视图可以从它们所属的状态继承已解析的依赖项,但可能不会继承它们的兄弟视图。

$stateProvider.state('myState', {
  resolve:{
     resMyState:  function(){
        return { value: 'mystate' };
     }
  },
  views: {
    'foo@myState': {
      templateUrl: 'mystate-foo.html',
      controller: function($scope, resMyState, resFoo){ 
        /* has access to resMyState and resFoo,
           but *not* resBar */ 
      },
      resolve: {
        resFoo: function() {
          return { value: 'foo' };
        }
      },
    },
    'bar@myState': {
      templateUrl: 'mystate-bar.html',
      controller: function($scope, resMyState, resBar){ 
        /* has access to resMyState and resBar,
           but *not* resFoo */ 
      },
      resolve: {
        resBar: function() {
          return { value: 'bar' };
        },
      },
    },
  },
});

Abstract States
抽象状态

An abstract state can have child states but can not get activated itself. An 'abstract' state is simply a state that can't be transitioned to. It is activated implicitly when one of its descendants are activated.
抽象状态可以有子状态,但不能被激活。一个“抽象”的状态就是一个不能被主动激活的状态。当它的一个后代被激活时,它会被隐式激活。

Some examples of how you might use an abstract state are:
一些关于如何使用抽象状态的例子是:

  • To prepend a url to all child state urls.
    将 url 预置为所有子状态 url。
  • To insert a template with its own ui-view(s) that its child states will populate.
    要将子状态插入自己的ui-view(s)的模板。
    • Optionally assign a controller to the template. The controller must pair to a template.
      (可选) 将控制器分配给模板。控制器必须与模板配对。
    • Additionally, inherit $scope objects down to children, just understand that this happens via the view hierarchy, not the state hierarchy.
      另外,将$scope对象继承给子对象,只需要知道这是通过视图层次结构而不是状态层次结构来实现的。
  • To provide resolved dependencies via resolve for use by child states.
    通过解析(Resolve)为子状态提供依赖关系。
  • To provide inherited custom data via data for use by child states or an event listener.
    通过数据为子状态或事件监听器提供可继承的自定义数据。
  • To run an onEnter or onExit function that may modify the application in someway.
    运行一个onEnter或onExit函数,它可以以某种方式修改应用程序。
  • Any combination of the above.
    以上的任何组合。

Remember: Abstract states still need their own <ui-view/> for their children to plug into. So if you are using an abstract state just to prepend a url, set resolves/data, or run an onEnter/Exit function, then you'll additionally need to set template: "<ui-view/>".
请记住:抽象的状态仍然需要他们自己的孩子去插入。因此,如果您正在使用一个抽象的状态来预先设置一个url,设置resolves/data,或者运行一个onEnter/Exit函数,那么您还需要设置模板:“”。

Abstract State Usage Examples:
抽象状态用法示例:

To prepend url to child state urls
将 url 追加到子状态 url

$stateProvider
    .state('contacts', {
        abstract: true,
        url: '/contacts',

        // Note: abstract still needs a ui-view for its children to populate.
        // You can simply add it inline here.
        template: '<ui-view/>'
    })
    .state('contacts.list', {
        // url will become '/contacts/list'
        url: '/list'
        //...more
    })
    .state('contacts.detail', {
        // url will become '/contacts/detail'
        url: '/detail',
        //...more
    })

To insert a template with its own ui-view for child states to populate
要插入一个带有自己的ui-view的模板来填充子状态

$stateProvider
    .state('contacts', {
        abstract: true,
        templateUrl: 'contacts.html'
    })
    .state('contacts.list', {
        // loaded into ui-view of parent's template
        templateUrl: 'contacts.list.html'
    })
    .state('contacts.detail', {
        // loaded into ui-view of parent's template
        templateUrl: 'contacts.detail.html'
    })
<!-- contacts.html -->
<h1>Contacts Page</h1>
<div ui-view></div>

Combination
组合

Shows prepended url, inserted template, paired controller, and inherited $scope object.
显示预先输入的url、插入的模板、成对的控制器和继承的$scope对象。

完整示例请参见: http://plnkr.co/edit/gmtcE2?p=preview

$stateProvider
    .state('contacts', {
        abstract: true,
        url: '/contacts',
        templateUrl: 'contacts.html',
        controller: function($scope){
            $scope.contacts = [{ id:0, name: "Alice" }, { id:1, name: "Bob" }];
        }    		
    })
    .state('contacts.list', {
        url: '/list',
        templateUrl: 'contacts.list.html'
    })
    .state('contacts.detail', {
        url: '/:id',
        templateUrl: 'contacts.detail.html',
        controller: function($scope, $stateParams){
          $scope.person = $scope.contacts[$stateParams.id];
        }
    })
<!-- contacts.html -->
<h1>Contacts Page</h1>
<div ui-view></div>
<!-- contacts.list.html -->
<ul>
    <li ng-repeat="person in contacts">
        <a ng-href="#/contacts/{{person.id}}">{{person.name}}</a>
    </li>
</ul>
<!-- contacts.detail.html -->
<h2>{{ person.name }}</h2>

探讨请加微信:


0
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:294790次
    • 积分:2993
    • 等级:
    • 排名:第12162名
    • 原创:85篇
    • 转载:10篇
    • 译文:5篇
    • 评论:154条
    最新评论