我可以修改从ui-router构建的url吗?

时间:2013-11-20 00:06:07

标签: angularjs angular-ui-router

我目前正在使用ui-router来管理我的angularjs应用程序中的路由,我想知道是否有办法修改创建的url。

用一个例子更好地解释了它。 我有以下状态

$stateProvider.state('items', {
  url: 'items/{itemName}',
  ...
 });

然后在我看来,我可以用

转换到这个状态
<a ui-sref="items({itemName:'Full Item Name'})">...</a>

,点击后,将网址设置为/items/Full%20Item%20Name 我想要做的是将生成的网址修改为/items/full-item-name,但仍然会在$ stateParams中显示Full Item Name

我已设法将导航的网址更改为我想要的

$rootScope.$on('$stateChangeStart',
        function(event, toState, toParams, fromState, fromParams) {    
            for (var prop in toParams) {
                var original = toParams[prop];
                var pretty = makePretty(original);

                toParams[prop] = pretty;
            }
        });

这会在路线发生变化之前将toParams更改为'美化'形式,这样网址就会是我想要的

这是一个插件:http://plnkr.co/edit/8AhkitxFjy7H6ZwTkeT4?p=preview

我现在缺少的主要内容是链接指向的网址仍为items/Full%20Item%20Name

我错过了什么吗?有没有更简单的方法来解决这个问题?

2 个答案:

答案 0 :(得分:1)

我们在未来版本中有一个名为typed parameters的功能,允许你这样做,但是现在,我建议的唯一两件事就是这样:

<a ui-sref="items({ itemName: slug('Full Item Name') })">...</a>

然后:

onEnter: function($stateParams) {
    $stateParams.itemName = deslug($stateParams.itemName)
}

或者,要全局执行此操作,请覆盖$state.href()(但您可能仍需要执行onEnter事项。)

答案 1 :(得分:0)

使用Nate的建议,这是我的解决方案:

app.run(function($rootScope, $state) {           

    // Store a copy of the original href function
    $state.baseHref = $state.href;
    $state.href = function href(stateOrName, params, options) {

        // slug each parameter that comes in
        for (var p in params) {
            params[p] = slug(params[p]);
        }
        // then call the original href function with the slugged params
        return $state.baseHref(stateOrName, params, options);
    };

    $rootScope.$on('$stateChangeSuccess',
        function(event, toState, toParams, fromState, fromParams) {
            // After the state has changed unslug the parameters so that
            // $stateParams.parameterName is the unslugged value
            for (var prop in toParams) {
                toParams[prop] = unslug(toParams[prop]);
            }
        });
});

这解决了创建slugged url的问题,并在状态转换之后但在创建控制器之前将其拔出。需要注意的一点是,在$stateChangeSuccess属性完成后会触发resolve,因此为了解决未插入的值,我必须执行以下操作:

resolve: {
    parameterName: function ($stateParams) {
        return unslug($stateParams.parameterName);
    }
}

如果您只是将$ stateParams注入控制器,则可以跳过最后一步。