UI 路由器匹配 url 与散列(片段)

UI Router matching url with hash (fragment)

使用 UI 路由器,我需要将 URLs 与其中包含的哈希(片段)相匹配(HTML5 模式)。

.state('myState', {
            url: '/path/:id/page#:section',
            templateUrl: 'template.html',
            controller: 'MyController'
        });

虽然上面的设置在使用下面的 ui-sref 时有效..

<a ui-sref="myState({id: 1})"> ... // without hash => section == ''
<a ui-sref="myState({id: 1, section: 'abc'})"> ... // section == 'abc'

.. 当我通过在地址栏中指定片段手动从其他页面重定向浏览器时失败(或者当 link 包括哈希在完全不同的站点上被单击时)在这种情况下 URL 匹配器尝试在没有散列的情况下与 URL 匹配,我被迫创建一个与上面相同但没有散列和参数 section 的新人工状态 url 属性。但这让我不可能拥有包含哈希的书签 URL。

我需要一个状态,其中此片段参数是可选的,并且在重定向到保留给定 section 的页面时通过应用内状态转换和 url 匹配机制正确匹配参数(如果存在)。

我通过使用 # 参数解决了这个问题:

<a ui-sref="myState({id: 1})"> ... // without hash => # == ''
<a ui-sref="myState({id: 1, '#': 'abc'})"> ... // # == 'abc'

和状态定义中的URL一起没有散列:

url: '/path/:id/page',

这将页面加载时的状态与 URL 中的散列相匹配,但它仍然没有在状态参数中设置 # 值。我通过在 $stateChangeStart 事件处理程序中手动设置参数解决了这个问题:

 $rootScope.$on('$stateChangeStart',
      function(event, toState, toParams, fromState, fromParams) {
            var hash = $location.hash();
            if (hash) {
                 toParams['#'] = hash;
            }
      }