我正在使用角度ui路由器,如下所示:
angular
.module('app', [
'ui.router'
])
.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('start', {
url: '/',
templateUrl: 'templates/start.html',
controller: 'startCtrl'
})
.state('dictionary', {
url: '/dictionary',
templateUrl: 'templates/dictionary.html',
controller: 'dictionaryCtrl'
})
}])
这很好用。
现在我想做的是继续从/ dictionary建立URL。
基本上,字典将包含一组重复的li元素,这些元素基于对象数组进行渲染。 请注意,对象数组是从源中检索的,该源可能会不时包含不同的对象集。
<ul>
<li ng-repeat="element in array">
{{element}}
</li>
</ul>
通过单击上面列表中的元素,控制器将更新数组,并根据childelements将上面的列表重新渲染到源中的相应元素。
首先,我希望将网址添加为:
/dictionary/selectedelement
如果我在浏览器中回复,我希望返回
/dictionary
如果我要加入书签
/dictionary/selectedelement
我希望能够根据最后一个网址片段呈现列表。
如果可能的话,我也想使用相同的控制器。
答案 0 :(得分:1)
如果我说得对,你有一个动态状态列表,你想使用同一个控制器。
像
这样的东西/dictionary/my-first-element
/dictionary/my-second-element
是吗?
嗯,这正是我们在Wishtack.com上用来处理i18n网址的原因。
我们有一个utils服务,其中包含一个从配置对象生成状态的方法。
在你的情况下,它只是看起来像这样(因为我们使用underscore.js):
stateList = _.map(stateConfigList, function (stateConfig) {
return {
controller: 'YourGenericController',
name: stateConfig.name,
url: '/dictionary/' + stateConfig.url,
/* You can add any field you want so you can have different behaviours depending on the state using the same controller. */
settings: stateConfig.settings
}
});
angular.forEach(stateList, function (state) {
$stateProvider.state(state.name, state);
});
您的控制器每个州可以有不同的行为:
$scope.showCrazyStuff = $state.current.settings.showCrazyStuff;
这就是你要找的东西吗?
关于后退按钮,您可以使用以下方式覆盖历史记录:
$window.history.pushState()
但是恕我直言,我认为这很麻烦,因为如果我来自你/ dictionary / my-first-element上的另一个网站并且我回击了,我希望我的浏览器回到我来自的网站而不是/字典。作为用户,我会感到被绑架。
最后一点,因为在配置阶段和服务注入之前使用$ stateProvider执行状态配置,AFAIK,我认为在控制器运行时有一种干净的方式来动态添加和删除状态。顺便说一句,再次出现这种行为会很奇怪,如果我来自外部网站,angular-ui-router应该已经知道所有可能的状态,以便知道应该运行哪个控制器,否则,我会被重定向到默认状态。
希望它有所帮助!
<强>更新强>
哦,哦!我在考虑更轻松的事情。为什么不声明这样的状态{url:'/ dictionary /:itemId'}然后在你的控制器中,你可以用“$ stateParams.itemId”来知道用户正在寻找哪个元素。第一个解决方案的主要优点是您可以为一组URL分配不同的控制器/模板对。
在Wishtack上,我们还使用了一种技巧,可以使用不同的控制器,具体取决于上下文:
.controller('Controller', function ($stateParams) {
if ($stateParams...) {
/* Yes, we use classes using dejavu and ControllerOne and ControllerTwo extend a base class ControllerBase. */
return new ControllerOne();
}
else {
return new ControllerTwo();
}
});