UI-Router父级状态可以访问其子级成员吗?

时间:2018-11-23 07:32:19

标签: angularjs angular-ui-router

我正在使用AngularJS的UI-Router来管理Web应用程序的路由。

我有两种状态:parent_statechild_state的排列如下所示。

$stateProvider
.state('parent_state', {
    abstract: true,
    views: {
        '@' : {
            templateUrl: 'http://example.com/parent.html',
            controller: 'ParentCtrl'
        }
    }
})
.state('child_state', {
    parent: 'parent_state',
    url: '/child',
    params: {
      myArg: {value: null}
    },
    views: {
      'mainarea@parent_state': {
          templateUrl: 'http://example.com/child.html',
          controller: 'ChildCtrl'
        }
    }
})

ChildCtrl中,我可以像这样访问myArg

app.controller("ChildCtrl", function($stateParams) {
    console.log('myArg = ', $stateParams.myArg);
});

我可以访问myArg并将其显示在html页面parent.html中吗?如果是这样,怎么办?我看到抽象状态的ParentCtrl控制器甚至从未被调用。

question解决了一个相关主题。但这没有告诉我如何在父状态的模板中显示子状态的参数。

3 个答案:

答案 0 :(得分:3)

我想到的第一件事是在孩子参数更改后使用事件通知父母。请参阅以下内容(您甚至可以在这里运行它)。

子项在渲染之后,使用参数的更改值向父项发出事件。父级抓取并显示在其自己的模板中。

<div class="expression">
  <span class="hidden">4</span>
  <span class="hidden">-</span>
  <span class="hidden">2</span>
  <span class="hidden">+</span>
  <span class="hidden">5</span>
  <span class="hidden">*</span>
  <span class="hidden">8</span>
  <span class="hidden">=</span>
  <span class="hidden">42</span>
  <div><button class="next">Next</button></div>
</div>
angular.module('myApp', ['ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
  $stateProvider
  .state('parent_state', {
    abstract: true,
    template: "<h1>Parent! Value from child: {{ paramFromChild }}</h1><div ui-view></div>",
    controller: function ($scope) {
      $scope.$on('childLoaded', function (e, param) {
        $scope.paramFromChild = param;
      });
    }
  })
  .state('child_state', {
    parent: 'parent_state',
    url: '/child',
    params: {
        myArg: {value: null}
    },
    template: '<h2>Child! Value: {{ param }}</h2>',
    controller: function($stateParams, $scope){ 
      $scope.param = $stateParams.myArg;
      $scope.$emit('childLoaded', $stateParams.myArg);
    }
  });
});

答案 1 :(得分:1)

  

我是否可以访问myArg并将其显示在   html页面 parent.html

这违反了UI路由器的原理。父母的参数可以在孩子身上食用,反之亦然。在不重新初始化控制器的情况下,父视图如何知道更改?您需要观看的东西。

真正的方法是雇用Multiple Named Views。看看这个工作plunkr

答案 2 :(得分:0)

是的,这是可能的。

  1. 使用 $ stateChangeSuccess

您可以使用 $ stateChangeSuccess 来实现。

例如:

.state('main.parent', {
  url: '/parent',
  controller: 'ParentController',
  controllerAs: 'vm',
  templateUrl: 'app/parent.html',
  data: {
    title: 'Parent'
  }
})
.state('main.parent.child', {
  url: '/child',
  controller: 'ChildController',
  controllerAs: 'vm',
  templateUrl: 'app/child.html'
})

在运行块中按如下所示调用它:

$rootScope.$on('$stateChangeSuccess', function (event, toState, fromState) {
  var current = $state.$current;
  if (current.data.hasOwnProperty('title')) {
    $rootScope.title = current.data.title;
  } else if(current.parent && current.parent.data.hasOwnProperty('title')) {
    $rootScope.title = current.parent.data.title;
  } else {
    $rootScope.title = null;
  }
});

然后,您可以从子控制器访问$ rootScope.title,因为它在全球范围内可用。

  1. 使用工厂或服务

通过编写setter和getter,可以在控制器之间传递数据。因此,您可以从子控制器设置数据,并从父控制器获取数据。

'use strict';
(function () {
    var storeService = function () {
        //Getters and Setters to keep the values in session
        var headInfo = [];
        return {
            setData: function (key, data) {
                headInfo[key] = data;
            },
            getData: function (key) {
                return headInfo[key];
            }
        };
    };
    angular.module('MyApp')
        .factory('StoreService', storeService);
})(angular);

从子控制器设置数据

StoreService.setData('title', $scope.title)

获取数据

StoreService.getData('title');
  1. 使用事件 $ emit,$ on

    您可以从子控制器发出作用域值,并在父作用域中监听它。