我使用的是Angular ui router,如下所示。
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'
})
}])
这样就可以了
现在我想做的是继续从字典中构建URL。
基本上,字典将包含一组重复的li元素,这些元素是基于一个对象数组渲染的,注意对象数组是从一个源中获取的,这个源可能会不时地包含一组不同的对象。
<ul>
<li ng-repeat="element in array">
{{element}}
</li>
</ul>
通过点击上面列表中的一个元素,控制器将更新数组,并基于childelements重新渲染上面的列表到源中的相应元素。
首先,我想把网址附加在后面,比如。
/dictionary/selectedelement
如果我在浏览器中点击回车,我希望回到...
/dictionary
如果我把它收藏起来
/dictionary/selectedelement
我希望能够根据最后的url段来渲染列表。
如果可能的话,我也希望使用同一个控制器。
如果我没理解错的话,你有一个动态状态的列表,你想使用同一个控制器。
类似于
/dictionary/my-first-element
/dictionary/my-second-element
是这样吗?
嗯,这正是我们在Wishtack.com上用来处理i18n urls的方法。
我们有一个utils服务,它有一个从配置对象生成状态的方法。
在你的情况下,它看起来就像这样(因为我们使用的是undererscore.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()
但我认为这是个黑客行为,因为如果我从另一个网站来到你的 dictionarymy-first-element 上,然后我回击,我希望我的浏览器能回到我来自的网站,而不是 dictionary。作为一个用户,我会觉得被绑架了。
最后一件事,由于状态配置是在配置阶段和服务注入之前使用$stateProvider进行的,AFAIK,我不认为有一个干净的方法可以在你的控制器运行时动态地添加和删除状态。顺便说一下,如果我来自一个外部网站,angular-ui-router应该已经知道所有可能的状态,以便知道它应该运行哪个控制器,否则,我将被重定向到默认状态,这样的行为会很奇怪。
希望能帮到你
更新。
哦,我在想一个更简单的办法。为什么你不像这样声明一个状态{ url: 'dictionary:itemId' } 然后在你的控制器中,你可以使用"$stateParams.itemId "来知道用户正在寻找哪个元素。
第一个解决方案的主要优点是,你可以为一组URL分配不同的controllerertemplate对。
在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();
}
});