使用 Angular UI-router 从父状态到子状态共享数据

Share data from parent to child state with Angular UI-router

基于此 tutorial,我有一个人员列表作为我的父状态。当我单击其中一个时,会创建一个新视图以显示该人的详细信息。在我的 URL 中,我使用那个人的 ID,因此很容易去获取要在子状态中使用的 ID。问题是我还想传递姓名,电子邮件,年龄等信息

代码如下:

我的路线:

angular
    .module('appRoutes', ["ui.router"])
    .config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {


    var TalentForceState_seeProfile = {
      name: 'students',
      url: '/seeProfile',
      templateUrl: 'public/templates/talentforce_template.html',
      controller: 'People_Controller'
    }

    var singleStudent = { 
      name: 'student',
      parent: 'students',
      url: '/:personId',
      templateUrl: 'public/templates/person_template.html',
      controller: 'Person_Controller'
    }

 ....

然后,People 的控制器:

talentforceApp
    .controller('People_Controller', ['$scope', '$state', '$stateParams', 'StudentService', function($scope, $state, $stateParams, StudentService) {

        StudentService.query().$promise.then(function(data) {
            $scope.students = data;
        });

}]);

然后,Person 的控制器:

talentforceApp
    .controller('Person_Controller', ['$scope', '$state', '$stateParams', 'StudentService', function($scope, $state, $stateParams, StudentService) {

$scope.student_id = $stateParams.personId;
console.log($stateParams)
}]);

此外,这里是 HTML 人:

<div ng-controller="Person_Controller">
    <h3>A person!</h3>
        <div>Name: {{student_name}}</div>
        <div>Id: {{student_id}}</div>
    <button ui-sref="students">Close</button>
</div>

student_name等信息是我好像不能从parent state传过来的

我尝试使用像 , that use $state.go, or 这样的解决方案,它使用 params,但它总是给我错误,例如 param values not valid for state 或变量未定义。

这个问题有什么解决办法吗?

您不能使用 $state.go 传递具有嵌套属性的大对象。您可以使用事件:广播、发出。创建一个服务来保存数据并将其共享给您的控制器是更好的方法。

您可以使用angular的状态resolve以更好的方式实现您的要求。虽然有很多选择。

程序:

  1. 加载父状态时,您查询 API 呼叫中的所有人。
  2. 在该响应中,我使用 studentService.addStudents($scope.students); 将响应分配给服务实例,其中 addStudents 是服务中的一个函数。
  3. 现在,当您导航到一个人的详细信息时,我使用了 resolve,它使用函数 studentService.getStudents() 和 returns 从服务中获取存储的数据 person 对象到控制器。
  4. 通过注入 resolve 变量
  5. 直接在 person 控制器中使用该 person 对象

我更喜欢使用 resolve。我来告诉你为什么。

这是您可以使用的解析:

resolve: {
    student: function(studentService, $stateParams) {
      return studentService.getStudents().find(function(student) { 
        return student.id === $stateParams.personId;
      });
    }
  }

您将添加一项服务 studentService 或者您可以扩展您自己的服务。

服务:

talentforceApp.service('studentService', function(){
  vm = this;
  vm.students = []

   this.addStudents = function(students) {
      vm.students = students;
   }

   this.getStudents = function() {
      return vm.students;
   }
});

我添加了 addStudentsgetStudents 方法。

一种方法将学生添加到数组中,另一种方法获取学生的数据。

人员控制器修改:

talentforceApp
    .controller('People_Controller', ['$scope', '$state', '$stateParams', 'StudentService', function($scope, $state, $stateParams, StudentService,studentService) {

        StudentService.query().$promise.then(function(data) {
            $scope.students = data;
            studentService.addStudents($scope.students); // this will create a students array in service instance
        });
}]);

我已将 $scope.students 分配给服务实例。

路线修订:

var TalentForceState_seeProfile = {
  name: 'students',
  url: '/seeProfile',
  templateUrl: 'public/templates/talentforce_template.html',
  controller: 'People_Controller'
}

var singleStudent = { 
  name: 'student',
  parent: 'students',
  url: '/:personId',
  templateUrl: 'public/templates/person_template.html',
  controller: 'Person_Controller',
  resolve: {
    student: function(studentService, $stateParams) {
      return studentService.getStudents.find(function(student) { 
        return student.id === $stateParams.personId;
      });
    }
  }
}

现在,您可以使用 student 从解析到您的控制器,作为依赖项。

个人控制器修改:

talentforceApp
    .controller('Person_Controller', ['$scope', '$state', '$stateParams', 'StudentService',student, function($scope, $state, $stateParams, StudentService,student) {
    $scope.student_id = $stateParams.personId;
    console.log($stateParams)
    $scope.student = student // this line add student to scope
    console.log($scope.student)
}]);

在视图中检查您的学生对象:

查看:

<div ng-controller="Person_Controller">
    <h3>A person!</h3>
         {{student}}
        <div>Name: {{student_name}}</div>
        <div>Id: {{student_id}}</div>
    <button ui-sref="students">Close</button>
</div>

here is why I prefer to use resolve and its advantages