角度“动态”/“通配符”路由

时间:2015-03-13 08:33:19

标签: angularjs angular-ui-router single-page-application browser-history

我正在使用角度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

我希望能够根据最后一个网址片段呈现列表。

如果可能的话,我也想使用相同的控制器。

1 个答案:

答案 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();
  }
});