我们说我有一个person
数据对象,可以是不同类型的人:
{
name: 'Clyde',
gender: 'male'
},
{
name: 'Jean',
gender: 'female'
}
所以,我有一个处理这个问题的视图状态,但我希望其中的细节不同......
国家
$stateProvider.state('person', {
url: '/person/:id',
templateUrl: 'person.html',
controller: 'PersonController',
resolve: {
personInstance: function($stateParams, dataModel) {
return dataModel.getPerson($stateParams.id);
}
}
};
查看 人:{{personInstance.name}}
好的,所以我有我的状态,但是我希望子状态代表我不同的多态视图:
$stateProvider
.state('person.male', {
templateUrl: 'person-male.html',
controller: 'PersonMaleController'
})
.state('person.female', {
templateUrl: 'person-female.html',
controller: 'PersonFemaleController'
});
冷却。但是......我该如何过渡到这个州?在数据结算之前,我不知道这是哪种类型的人。我是否需要在父母的onEnter
回调中执行此操作?
onEnter: function($state, $stateParams, personInstance) {
if(personInstance.gender === 'male') {
$state.go('person.male', $stateParams);
} else if(personInstance.gender === 'female') {
$state.go('person.female', $stateParams);
}
}
这似乎是合理的,但这样做会触发父状态,这会导致onEnter
事件,从而导致转换,这将永远发生。一般来说,这感觉有点偏,但我无法找到更好的方法来做到这一点。感觉有更好的方式。
修改
顺便说一下,我已尝试将其保留为单个状态,并在ng-switch
中执行person.html
并使用ng-include
包含模板,该模板明确设置控制器。但是那个孩子控制器并没有得到personInstance
传入的引用。这比我的反应更糟糕,但这是我尝试过的。
答案 0 :(得分:0)
您的解决方案很有效,除了您必须在PersonController
中进行重定向,这不是由子状态继承的。从父控制器重定向似乎也很合适,父控制器可以包含所有子类型共有的任何逻辑。
<!DOCTYPE html>
<html ng-app="app">
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="angular.js"></script>
<script src="angular-ui-router.js"></script>
</head>
<body>
<h1>Polymorphic States with ui-router</h1>
<div ui-view></div>
<script>
var app = angular.module('app', ["ui.router"]);
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/person/1");
$stateProvider
.state('person', {
url: '/person/:id',
//templateUrl: 'person.html',
template: '<h2>Generic Person Template</h2><ui-view></ui-view>',
controller: 'PersonController',
resolve: {
personInstance: function($stateParams, dataModel) {
return dataModel.getPerson($stateParams.id);
}
}
})
.state('person.male', {
template: '<h3>This is a male person view</h3>',
controller: 'PersonMaleController'
})
.state('person.female', {
template: '<h3>This is a female person view</h3>',
controller: 'PersonFemaleController'
})
;
});
app.controller('PersonController', function ($state, personInstance) {
// Do stuff here relevant to both genders.
if(personInstance.gender === 'male') {
$state.go('person.male');
} else if(personInstance.gender === 'female') {
$state.go('person.female');
}
});
app.controller('PersonMaleController', function ($state) {
});
app.controller('PersonFemaleController', function ($state) {
});
app.factory('dataModel', function($q){
return{
getPerson: getPerson
};
function getPerson(id){
var people = [
{
id: 1,
name: 'Clyde',
gender: 'male'
},
{
id: 2,
name: 'Jean',
gender: 'female'
}];
var person = {};
for(var i = 0; i < people.length; i++){
if (people[i].id == parseInt(id)) {
person = people[i];
}
}
return $q.when(person);
}
});
</script>
</body>
</html>