我有一个配置文件列表,其中每个配置文件可以是摘要或详细视图。任何时候只有一个配置文件可以有详细的视图。
profiles.html
<div ng-repeat="profile in profiles">
<div ui-view="profile-summary"></div>
<div ui-view="profile-details"></div>
</div>
个人资料-summary.html
<div ng-if="$state.params.profileId !== profile.id">
{{ profile.name }}
<button ng-click="showProfileDetails(profile.id)">More</button>
</div>
个人资料 - 摘要-controller.js
$scope.showProfileDetails = function(profileId) {
$state.go('profiles.profile', { profileId: profileId });
};
个人资料详情.html
<div ng-if="$state.params.profileId === profile.id">
Detailed profile of {{ profile.name }}
<button ng-click="hideProfileDetails()">Less</button>
</div>
个人资料-细节-controller.js
$scope.hideProfileDetails = function() {
$state.go('profiles.profile', { profileId: null });
};
ui-router配置
$stateProvider
.state('profiles', {
url: '/profiles?keywords',
views: {
'profiles': {
templateUrl: 'profiles.html',
controller: 'ProfilesCtrl'
},
'profile-summary@profiles': {
templateUrl: 'profile-summary.html',
controller: 'ProfileSummaryCtrl'
}
}
})
.state('profiles.profile', {
url: '/:profileId',
views: {
'profile-details': {
templateUrl: 'profile-details.html',
controller: 'ProfileDetailsCtrl'
}
}
});
我的问题:
ProfileDetailsCtrl
将被实例化3次。我怎样才能为扩展的配置文件实例化它?答案 0 :(得分:6)
在下面的评论中讨论后,基本(必需)概念有different solution:
在列表中 - 如何使用>>
ui-router
更多详细信
即。让我们从这开始:
点击更多2 (如果下次点击 Less 2 ,则返回
这将是解决方案:
1)列表视图模板将ng-if
,检查是否有 detail
信息:
<div ng-repeat="profile in profiles">
<div ng-if="!profile.detail">
<button ui-sref=".profile({profileId:profile.id})">More</button>
{{ profile.name }}
</div>
<div ng-if="profile.detail">
<button ui-sref=".">Less</button>
{{ profile.detail | json }}
</div>
</div>
要提到一些奇特的部分:我们只使用内置ng-click
并使用相对路径def ui-sref
而不是某些ui-sref=".profile({profileId:profile.id})"
- 这将调用子状态简介
加载子项后,我们可以通过重新调用父ui-sref="."
(哇...)
2)我们的 detail
州将会做两件事
休假时清理//按原样恢复列表
//从父系列中查找个人资料 var profile = _.find($ scope.profiles,{id:$ stateParams.profileId});
$ HTTP .get(&#34; detail.json&#34;)// getById 。然后(功能(响应){
// would contain just a detail for id... here we filter
var detail = _.find(response.data, {id : $stateParams.profileId});
// assign the detail
profile.detail = detail;
});
//清理 - 删除详细信息 var cleanup = function(){ 删除profile.detail; } $ scope。$ on(&#34; $ destroy&#34;,cleanup);
有几点值得一提:我们挂钩$scope
事件&#34;销毁&#34;。一旦我们回到父母那里,这将被解雇。这就是我们清理ui-router
详细州往返期间所有足迹的地方......
3)详细视图
没有。没有,因为我们不需要模板。实际上我们仍然需要视图锚点,其中放置了详细状态......并且调用了 DetailController
!
.state('profiles.profile', {
url: '/:profileId',
views: {
'profile-details': { // NO template
controller: 'ProfileDetailsCtrl'
}
}
});
所以父视图中必须有视图锚点
<div ui-view="profile-details"></div>
工作代码example :
看看那个解决方案here ... 它应该是明确的
(以下是为什么多次触发控制器的答案的原始部分)
控制器被多次实例化,因为它的视图被注入页面很多次。并且您确实将视图注入了3次。
以下是个人资料的来源
$scope.profiles = [
{ id: '100', name: 'Misko Hevery' },
{ id: '101', name: 'Igor Minar' },
{ id: '102', name: 'Vojta Jina' },
];
在这里,我们使用相同的ui-view
名称创建锚点/目标:
<div ng-repeat="profile in profiles"> // for each profile in our array
<div ui-view="profile-summary"></div>
<div ui-view="profile-details"></div> // we inject this view named profile-details
</div>
最后,我们要求将我们的观点注入这些(3)父/子视图目标:
.state('profiles.profile', {
url: '/:profileId',
views: {
'profile-details': { // the parent view-target is there 3 times
templateUrl: 'profile-details.html',
controller: 'ProfileDetailsCtrl'
}
}
});
解决方案:这不应该发生。我们不应该只使用一次ui-view="viewName"
。这是工作。但这不是我们能正确管理的......只需从转发器中移动目标......
EXTEND在这里我更新了plunker,我像这样制作了profiles.html
// NO repeater here
<div ui-view="profile-summary"></div>
<div ui-view="profile-details"></div>
我在摘要中进行了迭代:
<div ng-repeat="profile in profiles">
{{ profile.name }}
<button ng-click="showProfileDetails(profile.id)">More</button>
</div>
现在,每个ui-view
只有一次 ...请参阅here