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

问题描述 投票:71回答:5

如果不使用服务或在父控制器中构建观察者,如何让儿童状态访问主控制器的$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范围 - 或者说我正在获取该范围的另一个实例 - 而不是我想要的。我觉得我错过了一些简单的事情。状态对象中有一个共享数据配置选项,但我不确定是否应将此类用于此类。

javascript angularjs angularjs-scope angular-ui-router
5个回答
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获得定义的newcontroller实例。因此,虽然我们有mainController,如下所示,我们可以肯定,如果我们导航到状态'main.2'它将被实例化两次。

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

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

好吧,我所说的是:只有父州将启动$scope.Model。所有其他人都会得到充分的。怎么样?那么这里是答案:

Scope Inheritance by View Hierarchy Only

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

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

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

Understanding Scopes

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

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

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

就是这样。我们从UI-Router视图和角度范围获得继承,因为我们巧妙地使用了引用类型(Model),即在'.'定义中确实有ng-model点 - 我们现在可以共享数据

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

检查working example here


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 qazxsw poi并把它放在qazxsw poi上

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

$state

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


9
投票

这个想法是你在parent-> child inheritance中使用scope:

$scope

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


7
投票

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

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

1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.