当前位置: 首页 > 面试题库 >

ui路由器的作用域和控制器实例化

吴俊风
2023-03-14
问题内容

我对何时实例化控制器感到困惑。另外,嵌套状态时如何实例化控制器。我可能会感到困惑,如何将范围附加到视图和控制器,也就是说,如果每个视图都有自己的控制器和范围,或者它们共享相同的范围。

有人可以解释何时实例化控制器吗?在嵌套路由下,所有视图是否共享一个控制器和范围?当我切换状态并返回另一个控制器实例化的状态时会发生什么?

以下是我的路线(配置文件):

.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'
      }
    }
  })

问题答案:

要获得更详细的答案,我们可以/应该观察 源代码 并检查 文档 。让我尝试解释所有三个问题(并从代码和文档中引用)。

1.控制器何时实例化?

在这里,我们可以观察ui-view指令的代码:

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

控制器与 视图 相关。那些views在内定义.state()views 对象的:

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

所以,每当是 视图 (该ui-view)充满的状态视图的内部定义的设置,它的作用几乎作为一个 标准,但增强的指令

1)找到模板,
2)解决解析

x)实例化控制器…


视图目标(ui-view指令)可以使用名称,并且可以由层次结构中的不同状态填充。

这可能意味着,在一个视图 _(例如 title* )_内可能有一个内容,该内容由 父级 定义并且由 子级 替换 *

// 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"
  },
  ...
}

上面的状态定义 (无论何时在这两个状态之间进行转换) 都将:

  • 定义的$state.go('parent')-视图(模板,控制器…)'title@parent' : { ...}将被注入目标ui-view="title"并如上所述进行实例化

  • $state.go('parent.child')-几乎是相同的,只是视图将从子状态/图确定指标采取'title' : { ...}。它将替换和的内容,ui-view="title"并如上所述进行实例化

每当我们 从父母到孩子 以及 从孩子到父母 去做时,都会发生这种情况。

2.在嵌套路由下,所有视图是否共享一个控制器和范围?

一个简单的答案是“ 否”没有 共同的共享。

实际上, 每个控制器 都有 自己的作用域 ,即从父视图作用域创建的作用域。首先是文档:

儿童作用域从父作用域继承什么?

仅按视图层次结构的作用域继承

请记住,如果状态的视图是嵌套的,则范围属性仅沿状态链继承。范围属性的继承与状态的嵌套无关,而与视图(模板)的嵌套无关。

完全有可能存在嵌套状态,这些状态的模板会在站点内各个非嵌套位置填充ui视图。在这种情况下,您不能期望在子状态的视图中访问父状态视图的范围变量。

因此,只要将我们的controller _( 带有模板,控制器的 视图 …)_注入父对象的目标中,ui-view="..."它就会继承继承的范围:

newScope = scope.$new();

简而言之,这意味着 JS对象 _(例如scope.Model = {})_可以在子对象和父 对象 之间共享。

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

但是 ,基本Javascript类型不会通过引用传递,因此它们的值不会在范围之间自动同步:

// 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

3.当我切换状态并返回到状态时,会发生什么-另一个控制器是否被实例化?

这取决于。

如果将父子视图 ui-view="title"上面记住)_替换为子视图,然后将其重新创建 (从_ 子视图 过渡到父 视图 -则将重新初始化此类控制器(如上所述)。

但是,当我们谈论 主要的父视图 (通常是未命名的)时 ,它代表 了父 视图(例如,下面带有控制器“ParentMainCtrl”的未命名视图)

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

然后,我们可以确定该控制器没有重新实例化。它生活在所有孩子的寿命中,加上父母的 孩子(未选择孩子的状态)

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

[$ state.go(to,params,options)](http://angular-ui.github.io/ui-

router/site/#/api/ui.router.state.$state)

… options选项对象。选项包括:

  • 重载 - {boolean=false} ,如果即使国家或PARAMS没有改变,又名相同状态的重载真正将强制转换。它与reloadOnSearch有所不同,因为如果要在所有条件都相同(包括搜索参数)相同的情况下强制重新加载,则可以使用它。

希望那些对你有帮助。有关更多信息,请查看以下资源:

  • 嵌套状态和嵌套视图
  • 多个命名视图
  • API参考
  • State.js的示例应用程序 - 我想说的最好记录一段代码 永远


 类似资料:
  • 问题内容: 我想使用在视图中定义的一个控制器,但是没有定义任何东西。有没有办法做到这一点?请分享一个简单的例子以了解。 我有这个index.html 这是我的模型定义 app.js 控制台为空,并且html模板中的作用域为空。如果您有解决方案,请使用非常简单的示例。 我在这里阅读,我认为它起作用Rakrap Jaknap于2015-04-17 08:01回答 问题答案: 这里的重点是: 控制器始终

  • 问题内容: 一个单例控制器是否可能具有多个视图 [https://github.com/angular-ui/ui- router/issues/494] ? 用例:我有一个ui-view = header和ui-view = content。我根据当前状态更改标题以显示上下文相关的按钮(即返回,保存,过滤等)。我希望这些按钮在内容控制器中调用一个函数,但是如果执行以下操作,它将创建两个MyCon

  • 问题内容: 我有一个配置功能: InnerView位于mainView内部。当我获得url like时,函数按预期工作。但是,当我获得带有id的url时,即,我看不到任何输出,但是我希望输出,这就是我遇到的问题。我认为绝对/相对视图存在问题,但是我已经尝试了所有组合,但仍然无法正常工作。 更新: 所以现在我有以下状态: 正如RadimKöhler所说。输出,但是从现在开始我该如何到达? 问题答案:

  • 问题内容: 我试图在我的应用程序中编写通用路由,并根据路由参数动态解析视图和控制器名称。 我有以下有效的代码: 但是,我无法找到一种动态解析控制器名称的方法。我尝试使用此处所述的方法,但是ui- router似乎处理处理的方式与angular- route不同。 有指针吗? 编辑 :我已经尝试使用,但是对我不起作用(例如,以下代码仅返回一个硬编码的控制器名称,以测试其是否真正起作用): 给我以下错

  • 问题内容: 我正在尝试调用应该与 路线链接的控制器,但并未被调用。怎么了 问题答案: 好吧,我发现从给定的文件线索的的说 您可以为模板分配控制器。 警告: 如果未定义模板,则不会实例化控制器。 https://github.com/angular-ui/ui- router/wiki#controllers 但是我尝试添加,但仍然没有用,然后我发现我的父路由模板没有(我错误地删除了它),所以当我将

  • 问题内容: 我试图在UI-Router router.js文件中延迟加载控制器和模板,但是在模板处理上遇到困难。 控制器已正确加载,但是在加载之后,我们必须加载模板,这就是问题所在。 ocLazyLoad加载控制器后,我们解析了一个Angular Promise,它也包含在templateProvider中。问题在于,在文件加载完成后,不是返回诺言(templateDeferred.promise