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

如果不使用服务或在父控制器中构build监视器,如何让子控制器访问主控制器的$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作用域 – 或者我正在获取该作用域的另一个实例 – 而不是我想要的。 我觉得我错过了简单的事情。 状态对象中有一个共享的数据configuration选项,但是我不确定这是否应该用于这样的事情。

我创build了工作的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都获得了已定义controller new 实例 。 因此,虽然我们有如下所示的mainController ,但我们可以肯定的是,如果我们导航到状态'main.2' ,它将被实例化两次。

 controller('mainController', function ($scope) { $scope.Model = $scope.Model || {Name : "xxx"}; }) 

但是我们在这里可以看到的是,我们检查$scope.Model已经存在…如果没有(父状态)我们用新的实例 {Name : "xxx"} 实例化它。

那么,我说的是:只有父母国家将启动$scope.Model 。 所有其他人将得到已经填补。 怎么样? 那么这里是答案:

仅按视图层次结构进行范围inheritance

请记住,如果您的状态视图是嵌套的,范围属性只能沿着状态链inheritance。 范围属性的inheritance与嵌套状态无关,与嵌套视图(模板)无关。

完全可能的是,您的嵌套状态的模板在您的站点中的各种非嵌套位置处填充了ui-views。 在这种情况下,您不能期望在子状态视图内访问父状态视图的范围variables。

所以,如文件中所述。 因为我们的子视图嵌套在父视图中,所以范围是inheritance的。

了解范围

在AngularJS中,子范围通常从其父范围通常原型inheritance。

有一个 '。' 在你的模型中将确保原型inheritance的发挥。

 // So, use <input type="text" ng-model="someObj.prop1"> // rather than <input type="text" ng-model="prop1">. 

就是这样。 我们从UI-Router视图和angular度范围inheritance,因为我们巧妙地使用了一个引用types( Model ),也就是有'.'ng-model定义中的点 – 我们现在可以共享数据

注意:有点'。' ng-model="Model.PropertyName只是意味着有一个reference对象Model {}具有一些属性: PropertyName

检查这里的工作示例

你可以通过$ rootScope获得整个范围。 如果您只需要作用域的一部分,则ui-router具有自定义数据function。

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

首先,我有一些路由与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

这里是主要的模板'sign-up / index.html',:

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

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

这个想法是你在父 – >子inheritance中使用范围:

  .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),每个视图都有它自己的。

如果你正在使用嵌套视图只是不写任何其他控制器。 通过这种方式他们将共享相同的控制器数据。

 .state("main", { url: "/main", templateUrl: "templates/Ders", controller: "DersController as DersC" }).state("main.child1", { url: "/child1", templateUrl: "templates/Ders/child1" }).state("main.child2", { url: "/child2", templateUrl: "templates/Ders/child2" }) 

将共享variables分组到您可以在每个控制器中访问的服务中,是不是最简单的解决scheme? …