如何在angularjs ui-router中的状态之间共享$ scope数据?

时间:2014-12-29 21:54:40

标签: javascript angularjs angularjs-scope angular-ui-router

如果不在父控制器中使用服务或构建观察者,那么如何让儿童状态访问主控制器$scope

  .state("main", {
      controller:'mainController',
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

我无法访问子状态的mainController范围 - 或者说我正在获取该范围的另一个实例 - 而不是我想要的。我觉得我错过了一些简单的事情。 状态对象中有一个共享数据配置选项,但我不确定是否应将此类用于此类。

5 个答案:

答案 0 :(得分:107)

created working plunker,展示了如何使用$scope和UI-Router。

州定义未改变:

$stateProvider
    // States
 .state("main", {
      controller:'mainController',
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

但是每个州都有不同的控制器。为什么?因为每个的每个view都会获得定义new的{​​{1}} 实例。因此,虽然我们有controller类似下面的那个,但我们可以肯定,如果我们导航到状态mainController,它将被实例化两次。

'main.2'

但我们可以看到here,我们检查controller('mainController', function ($scope) { $scope.Model = $scope.Model || {Name : "xxx"}; }) 是否已经存在......如果不是(父状态)我们使用对其进行实例化新的意见 $scope.Model

好吧,我所说的是:只有父状态会初始化{Name : "xxx"}。所有其他人都会得到充分的。怎么样?那么这就是答案:

Scope Inheritance by View Hierarchy Only

  

请记住,只有嵌套状态的视图时,范围属性才会继承状态链。范围属性的继承与状态的嵌套无关,也与视图嵌套(模板)无关。

     

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

所以,正如文档中所述。因为我们的子视图嵌套在父视图中,所以范围是继承的。

Understanding Scopes

  

在AngularJS中,子范围通常原型继承自其父范围    ...

     

有一个'。'在你的模型中将确保原型继承发挥作用。

$scope.Model

就是这样。我们从// So, use <input type="text" ng-model="someObj.prop1"> // rather than <input type="text" ng-model="prop1">. 视图和角度范围获得继承,因为我们巧妙地使用了引用类型( UI-Router ),即{{1}中有Model点定义 - 我们现在可以共享数据

注意:有点&#39;。&#39;在'.'只是意味着, ng-model 对象ng-model="Model.PropertyName包含一些属性:reference

检查working example here

答案 1 :(得分:15)

您可以通过$rootScope获得整个范围。如果您只需要部分范围,则ui-router具有custom data功能。

以下是如何执行多步骤表单。我需要路由来包含有关他们在流程中的步骤的信息。

首先,我有一些带有UI路由器的路由:

  // Sign UP routes
  .state('sign-up', {
    abstract: true,
    url: '/sign-up',
    controller: 'SignupController',
    templateUrl: 'sign-up/index.html',
  })
  .state('sign-up.start', {
    url: '-start',
    templateUrl: 'sign-up/sign-up.start.html',
    data: { step: 0, title: 'Welcome to Mars!', },
  })
  .state('sign-up.expertise', {
    url: '-expertise',
    templateUrl: 'sign-up/sign-up.expertise.html',
    data: { step: 1, title: 'Your Expertise'},
  })

注意:

  • 每条路线中的data元素。
  • abstract州有SignupController。这是这个多步形式的唯一控制器。 abstract并非必需,但对此用例有意义。

SignupController.js

angular.module('app').controller('SignupController', function($scope, $state) {
  $scope.state = $state;
});

在这里,我们获取ui-router的$state并将其置于$scope

以下是主要模板&#39;注册/ index.html&#39;,

<h2>{{state.current.data.title}}</h2>

<div>This is a multi-step-progress control {{state.current.data.step}}</div>

<form id="signUpForm" name="signUpForm" novalidate>
  <div ui-view></div>
</form>

子模板可以是他们喜欢的任何东西。

答案 2 :(得分:9)

这个想法是你在parent-&gt;子继承中使用范围:

 .state("main", {
      controller:'mainController',
      abstract: true,
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController1',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController2',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

比用法简单,你有3个控制器,一个是共享的(mainController),每个视图都有它自己的。

答案 3 :(得分:7)

如果您使用嵌套视图,则不要编写任何其他Controller。通过这种方式,他们将共享相同的控制器数据。

OnCommand="btnSearch_Click"

答案 4 :(得分:1)

将共享变量分组到您可以在每个控制器中访问的服务中,这不是最简单的解决方案吗? ...