与UI路由器范围和控制器实例 [英] scope and controller instantiation with ui router

查看:107
本文介绍了与UI路由器范围和控制器实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我感到困惑时,控制器被实例化。此外,该怎么办控制器被实例化嵌套的状态时。范围如何被附加到视图和控制器我可能会感到困惑,那就是,如果每个观点都有自己的控制器和范围,或者说它们共享相同的范围。

有人可以请解释当控制器被实例化?在嵌套的路线做所有的视图共享一个控制器和范围?当我切换状态,回到一个国家并另一个控制器被实例化,会发生什么?

下面是我的路线:
    的.config(googleAnalyticsCordovaProvider,$ stateProvider,$ urlRouterProvider,IdleProvider,KeepaliveProvider) - >

  $ stateProvider  .STATE('应用',{
    网址:'/应用程序',
    摘要:真实,
    templateUrl:'模板/ menu.html',
    控制器:'AppController的
  })  .STATE('app.pin code',{
    网址:'/针code',
    观点:{
      menuContent:{
        templateUrl:'模板/针code-yield.html',
        控制器:'脚$ C $的CController
      }
    }
  })  .STATE('app.pin code.create',{
    网址:'/创建,
    观点:{
      销code:{
        templateUrl:'模板/针code-create.html上',
        控制器:'脚$ C $的CController
      }
    }
  })  .STATE('app.pin code.pin codeLogin',{
    网址:'/登录',
    观点:{
     销code:{
        templateUrl:'模板/针code-的login.html',
        控制器:'脚$ C $的CController
      }
    }
  })  .STATE('app.pin code.settings',{
    网址:/设置
    观点:{
      销code:{
        templateUrl:'模板/ settings.html',
        控制器:'脚$ C $的CController
      }
    }
  })


解决方案

要得到更详细的答案,我们可以/应遵守的来源$ C ​​$ C 并检查文件。让我试着解释所有三个问题(以及从code和DOC引用)。


  

1。什么时候控制器被实例化?


在这里,我们可以观察到用户界面视图指令的code:

[$ ViewDirective $注入= \\ ['$状态,$喷油器','$ uiViewScroll','$插值'\\];] [1]

控制器都与的意见。那些的意见,其内部定义的 .STATE() 意见 对象:

  .STATE('...',{
  //视图定义
  观点:{
    '':{
      模板:...
      控制器:...
      解析:..
    }
  },
  解决:...
}

所以,当是的视图的(即用户界面视图)充满状态视图中定义的设置,它的行为几乎成了< STRONG>标准,但提高了指令。

1)模板被发现,结果
2)的决策,解决结果
...结果
x)的控制器被实例化...

查看目标(用户界面视图指令)可以使用的名称,并且可以通过不同的状态层次结构中的填充。

这可能意味着,有可能是一个视图里面内容的(如标题的,由父定义以及更换通过孩子

  //父
.STATE('父',{
  观点:{
    '':{...} //主父视图,用户界面​​视图=标题
    '称号@父:{...} //这里我们去,并填写家长的UI视图=标题
  },
  ...
}//子
.STATE('parent.child',{
  观点:{
    标题:{...} //这里我们改变家长的目标用户界面视图=标题
  },
  ...
}

以上状态定义将的(每当我们在这两个状态之间转换)的事:


  • $ state.go(父) - 在定义的视图(模板,控制器......)称号@parent:{...} 将被注入到目标用户界面视图=标题和上面的实例

    描述

  • $ state.go('parent.child') - 几乎是一样的,只是认为从孩子的状态/视图确定指标<采取code>标题:{...} 。这将取代用户界面视图=称号的内容,将上述

    描述实例化

这会发生,每次我们干什么去的从父到子的和的从小孩到父


  

2。在嵌套的路线做所有的视图共享一个控制器和范围?


一个简单的答案是,有共同分享。

其实,每个控制器自己的作用域,它是从父视图范围内创建一个。首先文档:


  

<一href=\"https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#what-do-child-states-inherit-from-parent-states\">What做儿童的国家从父项继承国?


  
  

...


  
  

Scope通过视图层次只有

继承
  
  记

记住,如果你的国家的意见是嵌套作用域属性只继承下来的状态链。作用域属性的继承无关,与你的国家的嵌套和一切与你的视图(模板)嵌套。


  
  

这是完全可能的,你嵌套状态的模板填充在站点内的各种非嵌套位置UI的意见。在这种情况下,你不能指望子女国的意见内访问的父状态视图的范围变量。


所以,只要是我们的控制器(井查看与模板,控制器......)的注入家长的目标用户界面视图=...它会继承范围:

  newscope的范围= $新的()。

这简而言之手段 JS对象 (如 scope.Model = {} 的可共享其中儿童和家长。

  $ scope.Model.id = 1; //将引用两家母公司及放大器相同的ID;儿童

然而,基本的JavaScript类型不按引用传递,因此它们的值并不范围之间自动同步:

  //在父母设定
$ scope.id = 1;
//儿童后仍inherted 1 ===
$ scope.id = 2; //现在2个孩子,在父母不同的价值 - 仍然=== 1

这是值得一读更多关于这里的原型继承:结果
什么范围原型的细微差别AngularJS /原型继承?


  

3。当我切换状态,回到一个国家会发生什么? - 不另一个控制器被实例化


这要看情况。

如果父子视图的(记得用户界面视图=标题以上)的被子视图代替,那么它是重-created的(从孩子家长转变)的 - 例如控制器西港岛线进行重新初始化(如上所述)

但是,当我们谈论的主父视图 (通常未命名)的,从而重新presents (例如下面控制器ParentMainCtrl')无名视图

  .STATE('父',{
  观点:{
    '':{// //主父视图
      控制器:'ParentMainCtrl',
    }
    '称号@父
    提示@父
  },

然后,我们可以肯定,这种控制器没有重新实例。它的所有儿童的一生中生活,再加上父母的有一个(没有选择子状态)的。

要重新加载这个视图/控制器,我们必须使用一个选项重新加载

$ state.go(于参数,可以选择)


  

...
  选择Options对象。选项​​有:



  • ...

  • 重新加载 - {布尔= FALSE} ,如果属实,将迫使过渡即使国家或PARAMS有没有改变,又名相同的状态重新加载。它不同于reloadOnSearch因为你用这个当你要强制时,一切都是一样的,包括搜索PARAMS重载。

希望有点帮助。欲了解更多信息,请查看以下资源:

I am confused about when controllers get instantiated. Also, how do controllers gets instantiated when nesting states. I might be confused how scope gets attached to view and controller, that is, if every view gets its own controller and scope or do they share the same scope.

Can someone please explain when controllers get instantiated? Under nested routes do all the views share one controller and scope? What happens when I switch states and go back to a state does another controller get instantiated?

Below are my routes: .config (googleAnalyticsCordovaProvider, $stateProvider, $urlRouterProvider, IdleProvider, KeepaliveProvider) ->

   $stateProvider

  .state('app', {
    url: '/app',
    abstract: true,
    templateUrl: 'templates/menu.html',
    controller: 'AppController'
  })

  .state('app.pincode', {
    url: '/pincode',
    views: {
      menuContent: {
        templateUrl: 'templates/pincode-yield.html',
        controller: 'PincodeController'
      }
    }
  })

  .state('app.pincode.create', {
    url: '/create',
    views: {
      pincode: {
        templateUrl: 'templates/pincode-create.html',
        controller: 'PincodeController'
      }
    }
  })

  .state('app.pincode.pincodeLogin', {
    url: '/login',
    views: {
     pincode: {
        templateUrl: 'templates/pincode-login.html',
        controller: 'PincodeController'
      }
    }
  })

  .state('app.pincode.settings', {
    url: '/settings',
    views: {
      pincode: {
        templateUrl: 'templates/settings.html',
        controller: 'PincodeController'
      }
    }
  })

解决方案

To get even more detailed answers, we can/should observe the source code and check the documentation. Let me try to explain all three questions (and also cite from code and doc).

1. When do controllers get instantiated?

Here we can observe the code of the ui-view directive:

[$ViewDirective.$inject = \['$state', '$injector', '$uiViewScroll', '$interpolate'\];][1]

Controllers are related to views. Those views, which are defined inside of a .state() as the views object:

.state('...', {
  // The view definition
  views : {
    '' : {
      template: ...
      controller: ...
      resolve: ..
    }
  },
  resolve: ...
}

So, whenever is view (the ui-view) filled with settings defined inside of a state view, it acts almost as a standard, but enhanced directive.

1) Template is found,
2) Resolves are resolved
...
x) Controller is instantiated...

View targets (ui-view directives) could use names, and could be filled by different states in the hierarchy.

It could mean, that there could be a content inside of one view (e.g. title), defined by parent as well as replaced by child

// parent
.state('parent', {
  views : {
    '' : {...} // the main parent view, with ui-view="title"
    'title@parent' : { ...} // here we go and fill parent's ui-view="title"
  },
  ...
}

// child
.state('parent.child', {
  views : {
    'title' : { ...} // here we change the parent's target ui-view="title"
  },
  ...
}

The above state definition will (whenever we transition among these two states) do:

  • The $state.go('parent') - the view (template, controller...) defined in 'title@parent' : { ...} will be injected into target ui-view="title" and instantiated as described above

  • The $state.go('parent.child') - almost the same, just the view will be taken from child state/view defintion 'title' : { ...}. That will replace the content of the ui-view="title" and will be instantiated as described above

This will be happening every time we do go from parent to child and from child to parent.

2. Under nested routes do all the views share one controller and scope?

A simple answer is NO, there is no common sharing.

In fact, each controller has its own scope, the one which is created from parent view scope. Firstly the documentation:

What Do Child States Inherit From Parent States?

...

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.

So, whenever is our controller (well the view with template, controller...) injected into parent's target ui-view="..." it gets inherited scope:

newScope = scope.$new();

That in a nutshell means that JS objects (e.g. scope.Model = {}) can be shared among child and parent.

$scope.Model.id = 1; // will refer to the same id in both parent & child

However, basic Javascript types are not passed by reference, and so their values are not automatically synchronised between scopes:

// set in parent
$scope.id = 1;
// in child after inherted still === 1
$scope.id = 2; // now 2 for a child, different value in parent - still === 1

It's worth reading more about prototypical inheritance here:
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

3. What happens when I switch states and go back to a state - does another controller get instantiated?

It depends.

If the parent sub view (remember ui-view="title" above) is replaced by child view, and then it is re-created (transitioning from child to parent) - such controller wil be re-initialized (discussed above).

But when we speak about the main parent view (usually unnamed), which represents the parent (For example the unnamed view below with controller 'ParentMainCtrl')

.state('parent', {
  views : {
    '' : {  //  // the main parent view
      controller: 'ParentMainCtrl',
    }
    'title@parent'
    'tooltip@parent'
  },

Then we can be sure that such controller is NOT re-instantiated. It lives during the lifetime of all its children, plus a parent's one (no child state selected).

To re-load this view/controller, we have to use an option reload

$state.go(to, params, options)

... options Options object. The options are:

  • ...
  • reload - {boolean=false}, If true will force transition even if the state or params have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd use this when you want to force a reload when everything is the same, including search params.

Hope that helps a bit. For further information, check out these resources:

这篇关于与UI路由器范围和控制器实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆