Angular UI Router——当使用UI -sref导航到动态状态时,会得到双斜杠

Angular UI Router - Dynamic states get double slashes when navigated to with ui-sref

本文关键字:UI 状态 动态 -sref Angular 导航 Router      更新时间:2023-09-26

我正在创建一个CMS系统,所以我希望动态创建状态。由于不能在配置阶段发出http请求,所以我决定在.run()函数中添加路由,如下所示:http://blog.brunoscopelliti.com/how-to-defer-route-definition-in-an-angularjs-web-app

现在,当我在导航部分使用ui-sref指令显示链接列表时,附加的url有两个正斜杠而不是一个。控制器和所有东西都相应地调用,但我似乎无法摆脱双斜杠。什么好主意吗?

相关代码如下:

app.js

var $stateProviderReference;
angular.module('app', [
    'ui.router',                // Angular UI Routing
    'ngStorage',                // Angular Storage (local, cookies, session)
    'ngAnimate',                // Angular Animation
    'angular-loading-bar',      // Angular Loading Bar
    'restangular',              // Restangular
    'angular.assets.injector',  // Custom assets injector
])
.config(function($stateProvider, $urlRouterProvider, RestangularProvider, $httpProvider, cfpLoadingBarProvider){
    // Save a reference of our stateProvider
    $stateProviderReference = $stateProvider;
    // Irrelevant configuration
    // States (routes)
    $stateProvider
        /*
         |
         | Frontend
         |
         */
        .state('frontend', {
            url: '/',
            views: {
                '': { 
                    templateUrl: 'app/views/frontend/templates/default/bootstrap.html',
                    controller: 'FrontendCtrl'
                },
                'nav@frontend': {
                    templateUrl: 'app/views/frontend/templates/default/partials/navigation.html',
                    controller: 'NavCtrl',
                    resolve: {
                        pages: function(PageService){
                            return PageService.all();
                        }
                    }
                },
                'footer@frontend': {
                    templateUrl: 'app/views/frontend/templates/default/partials/footer.html',
                    controller: 'FooterCtrl'
                },
                'page@frontend': {
                    templateUrl: 'app/views/frontend/pages/page.html',
                    controller: 'PageCtrl'
                }
            }
        });
.run(function($rootScope, $location, $state, $stateParams, AuthService, CSRF_TOKEN, PageService){
    // Retrieve all the pages
    PageService.all().then(function(pages){
    // Loop through all the pages
    angular.forEach(pages, function(page){
        // If this is not the homepage
        if( page.routeName !== 'frontend' )
        {
            // Add a state to our stateProvider
            $stateProviderReference.state(page.routeName, {
                // Set the desired url
                url: page.url,
                // Views that we are populating
                views: {
                    // Override the page view partial
                    'page@frontend': {
                        templateUrl: 'app/views/frontend/pages/page.html',
                        controller: 'PageCtrl'
                    }
                }
            });
        }
    });
});

navigation.html部分

<ul class="nav navbar-nav">
    <li ng-repeat="page in pages">
        <a ng-class="{'active': isActive({{page.routeName}})}" ui-sref="{{ page.routeName }}">{{ page.title }}</a>
    </li>
</ul>

从数据库中检索到的页面数据格式如下:

{
    id: 1,
    routeName 'frontend.home',
    title: 'Homepage',
    url: '/home',
    metaData: {
        tags: "some random tags",
        desc: "some random description"
    },
    content: "Html goes here",
    deletable: 'yes' // or 'no'
}

所以除了双斜杠之外,一切似乎都工作了。当我点击为上面示例代码生成的链接时,它会将我发送到以下url:

http://localhost/CMSv2/public/#//home

代替

http://localhost/CMSv2/public/#/home

我已经尝试从routeName属性中删除正斜杠,然后它不附加双斜杠,但控制器再也无法到达,一切似乎都中断了。

这个问题来自于这样一个事实,即如果存在父-子状态,那么它们的url就是父。Url + child.url:

  • parent: .state('frontend', { url: '/',...
  • child: { routeName 'frontend.home', url: '/home',..
  • result: '/' + '/home' === '//home'

但是ui-router中有一个很好的解决方案:

  • 绝对路由(^)

小引号:

如果你想要绝对的url匹配,那么你需要在你的url字符串前加上一个特殊的符号'^'。

$stateProvider
  .state('contacts', {
     url: '/contacts',
     ...
  })
  .state('contacts.list', {
     url: '^/list',
     ...
  });

解决方案:(在这种情况下很容易)

代替url def:

{
    id: 1,
    routeName 'frontend.home',
    title: 'Homepage',
    url: '/home',
    ...

我们将这个 url: '^/home', :

{
    id: 1,
    routeName 'frontend.home',
    title: 'Homepage',
    url: '^/home',
    ...

由于您的home-state是从front -state派生的,所以额外的斜杠是从front -url添加的。要删除额外的初始斜杠,将前端状态设置为"abstract"并清除url,如下所示:

.state('frontend', {
    abstract: true,
    url: '',
    templateUrl: 'yourTemplate.html'
})

这也更符合你的结构,因为前端状态的url永远不会被使用。