【问题标题】:Angular UI Router - Dynamic states get double slashes when navigated to with ui-srefAngular UI 路由器 - 使用 ui-sref 导航到动态状态时会出现双斜杠
【发布时间】:2014-08-25 20:50:10
【问题描述】:

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

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

以下是相关代码:

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'
}

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

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

而不是

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

我尝试从 routeName 属性中删除正斜杠,然后它没有附加双斜杠,但无法再访问控制器,一切似乎都坏了。

【问题讨论】:

    标签: javascript angularjs angular-ui-router


    【解决方案1】:

    问题来自这样一个事实,如果有父子状态,他们的 url 是 parent.url + child.url:

    • 家长:.state('frontend', { url: '/',...
    • 孩子:{ routeName 'frontend.home', url: '/home',..
    • 结果:'/' + '/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',
        ...
    

    【讨论】:

      【解决方案2】:

      由于您的 home-state 是从 frontend-state 派生的,因此额外的斜杠是从 frontend-url 添加的。 要删除额外的初始斜线,请将前端状态设置为“抽象”并清除 url,如下所示:

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

      这也更符合您的结构,因为从不使用前端状态 url。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-12
        • 1970-01-01
        • 2016-09-22
        • 2015-03-26
        • 1970-01-01
        • 1970-01-01
        • 2016-02-01
        • 2014-04-08
        相关资源
        最近更新 更多