UI-路由器父状态可以访问它的子成员吗?
Can a UI-Router parent state access it's child's members?
我正在使用 AngularJS 的 UI-Router 来管理我的 Web 应用程序的路由。
我有两个状态:parent_state
和child_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 解决了一个相关主题。但是它没有告诉我如何在父状态的模板中向子状态显示参数。
我首先想到的是在子参数更改后使用事件通知父对象。请参阅以下内容(您甚至可以在此处 运行)。
子项在渲染后向父项发送一个事件,其中包含更改后的参数值。父抓取并显示在自己的模板中。
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);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.20/angular-ui-router.js"></script>
<div ng-app="myApp">
<a ui-sref="child_state({myArg: 'first'})">First link</a>
<a ui-sref="child_state({myArg: 'second'})">First second</a>
<div ui-view></div>
</div>
Is it possible for me to access myArg
and have it displayed in the
html page parent.html?
这违反了UI-Router的原则。 Parent 参数可以在 children 中使用,但反之则不行。父视图如何在不重新初始化控制器的情况下知道更改?你需要像看一样的东西。
真正的方法是使用Multiple Named Views. Look at this working plunkr。
是的,这是可能的。
- 使用 $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'
})
并在runblock中调用如下:
$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,因为它是全局可用的。
- 使用工厂或服务:
通过编写 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');
使用事件 $emit, $on:
您可以从子控制器发出作用域值并在父作用域中侦听它。
我正在使用 AngularJS 的 UI-Router 来管理我的 Web 应用程序的路由。
我有两个状态:parent_state
和child_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 解决了一个相关主题。但是它没有告诉我如何在父状态的模板中向子状态显示参数。
我首先想到的是在子参数更改后使用事件通知父对象。请参阅以下内容(您甚至可以在此处 运行)。
子项在渲染后向父项发送一个事件,其中包含更改后的参数值。父抓取并显示在自己的模板中。
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);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.20/angular-ui-router.js"></script>
<div ng-app="myApp">
<a ui-sref="child_state({myArg: 'first'})">First link</a>
<a ui-sref="child_state({myArg: 'second'})">First second</a>
<div ui-view></div>
</div>
Is it possible for me to access
myArg
and have it displayed in the html page parent.html?
这违反了UI-Router的原则。 Parent 参数可以在 children 中使用,但反之则不行。父视图如何在不重新初始化控制器的情况下知道更改?你需要像看一样的东西。
真正的方法是使用Multiple Named Views. Look at this working plunkr。
是的,这是可能的。
- 使用 $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'
})
并在runblock中调用如下:
$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,因为它是全局可用的。
- 使用工厂或服务:
通过编写 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');
使用事件 $emit, $on:
您可以从子控制器发出作用域值并在父作用域中侦听它。