简体   繁体   English

AngularUI路由器:具有相同url模式的多个状态

[英]AngularUI Router: multiple states with same url pattern

Hey all I'm running into what I thought would be a common routing problem, but I'm unable to figure out a solution. 嘿所有我遇到了我认为常见的路由问题,但我无法找到解决方案。 Basically my page has two states, basic and advanced, and I want the URL patterns to be the same for both states but only load the template for the current state at the time (which is transitioned to from within a controller) 基本上我的页面有两种状态,基本和高级,我希望两种状态的URL模式相同,但只加载当前状态的模板(从控制器内转换到)

config(function ($stateProvider) {

  $stateProvider.state('basic', {
    url: '/:post',
    templateUrl: function (stateParams) {
      return 'post-' + stateParams.post + '-tmpl.html';
    }
  });

  $stateProvider.state('advanced', {
    url: '/:post',
    templateUrl: function (stateParams) {
      return 'post-' + stateParams.post + '-advanced-tmpl.html';
    }
  });
})

controller('myCtrl', function ($state) {
  //
  // In this case, I would expect only the template from
  // the advanced state to load, but both templates are trying
  // to load.
  $state.transitionTo('advanced', {post: 2});
}

I assume that navigating to the matched pattern loads the given state which is why when it matches, both templates attempt to load. 我假设导航到匹配的模式会加载给定的状态,这就是为什么当它匹配时,两个模板都会尝试加载。 Is there some way to accomplish the same url pattern but with different templates based only on the current state? 有没有办法完成相同的网址模式,但只使用基于当前状态的不同模板?

Assuming that you cannot have two states with the same URL, why don't you go along and merge the two states into one? 假设您不能拥有两个具有相同URL的状态,为什么不同时将这两个状态合并为一个? Ui-router already allows you to have a custom function to return the template. Ui-router已经允许你有一个自定义函数来返回模板。 You just need to add another, hidden custom parameter (let's call it advanced ) to the state declaration: 您只需要向状态声明添加另一个隐藏的自定义参数(让我们称之为advanced ):

$stateProvider.state('basicOrAdvanced', {
  url: '/:post',
  templateUrl: function (stateParams) {
    if (stateParams.advanced) {
      return 'post-' + stateParams.post + '-advanced-tmpl.html';
    } else {
      return 'post-' + stateParams.post + '-tmpl.html';
    }
  },
  params: {
    advanced: False
  }
});

And then you call it with: 然后你用它来称呼它:

$state.transitionTo('basicOrAdvanced', {post: 2, advanced: True})

For another possible solution with nested states and a common controller, see issues #217 and #1096 on ui-router's github page. 有关嵌套状态和公共控制器的另一种可能解决方案,请参阅ui-router的github页面上的问题#217#1096

The solution presented there creates a third state whose controller does the dispatching work, whereas the two states you want to land in ( basic and advanced ) have empty URLs: 在那里提出的解决方案创建了第三个状态,其控制器执行调度工作,而您要登陆的两个状态( basicadvanced )具有空URL:

$stateProvider.state('basicOrAdvanced', {
  url: '/:post',
  controller: function($state, $stateParams) {
    if($stateParams.advanced) {
        $state.go('advanced', {post: $stateParams.post});
    } else {
        $state.go('basic', {post: $stateParams.post});
    }
  },
  params: {
    advanced: False
  }
}

This solution is better if your states differ in more aspects than the simple templateUrl (eg if they have completely separate controllers, etc.) 如果您的状态在简单templateUrl方面有所不同(例如,如果它们具有完全独立的控制器等),则此解决方案会更好


Also see another question on StackOverflow about a similar issue . 另请参阅StackOverflow上有关类似问题的另一个问题

This is very useful in AngularJS , 这在AngularJS中非常有用,

You Can Specify Dynamic Route for Multiple State with same url pattern 您可以使用相同的URL模式为多个状态指定动态路由

My Code is As follow that can be useful for you, 我的代码如下,对您有用,

Module Intialization, 模块初始化,

var app = angular.module("koops_app", ['ui.router','ui.bootstrap']);    //here you have to define all your required module for your project that you should inject...

Further, 进一步,

app.config(function ($locationProvider, $httpProvider, $stateProvider, $urlRouterProvider, $wampProvider) {


    // When No Routing i.e Default Routing
    $urlRouterProvider.when('', '/dashboard');


    // 404
    $stateProvider.state("404", {
        url: "/404",
        templateUrl: 'template/404.html',
    });


    // When Only One Argument i.e. Only Module Name
    $stateProvider.state("default", {
        url: "/:section",
        templateUrl: 'views/View-to-be-load.html',  //can use $stateParams.section for dynamic
        reload: true,
        resolve: {
            loadController: ['$q', '$stateParams', '$state',
                        function ($q, $stateParams, $state) {
                            var deferred = $q.defer();
                            deferred.resolve();
                            return deferred.promise;
                        }
                    ]
        },
        controllerProvider: function ($stateParams) {
            return 'controllerName';
        }
    });



        // When Two Argument i.e. Module/Controller
        $stateProvider.state("default/title", {
            url: "/:section/:title",
            templateUrl: 'views/View-to-be-load.html',  //can use $stateParams.section for dynamic
            reload: true,
            resolve: {
                loadController: ['$q', '$stateParams', '$state',
                            function ($q, $stateParams, $state) {
                                var deferred = $q.defer();
                                deferred.resolve();
                                return deferred.promise;
                            }
                        ]
            },
            controllerProvider: function ($stateParams) {
                return 'controllerName';
            }
        });



        // When Three Arguments i.e. Module/Controller/id
        $stateProvider.state("default/title/id", {
            url: "/:section/:title/:id",
            templateUrl: 'views/View-to-be-load.html',  //can use $stateParams.section for dynamic
            reload: true,
            resolve: {
                loadController: ['$q', '$stateParams', '$state',
                            function ($q, $stateParams, $state) {
                                var deferred = $q.defer();
                                deferred.resolve();
                                return deferred.promise;
                            }
                        ]
            },
            controllerProvider: function ($stateParams) {
                return 'controllerName';
            }
    });



        // Otherwise
        $urlRouterProvider.otherwise("/404");

May be this is helpful for you... Enjoy... 可能这对你有帮助...享受......

You need to use nested states 您需要使用嵌套状态

config(function ($stateProvider) {


  $stateProvider.state('post', {
    url: '/:post',
    templateUrl: function (stateParams) {
      return 'post-' + stateParams.post + '-advanced-tmpl.html';
    }
  });

   $stateProvider.state('post.basic', {
    url: '/:post',
    templateUrl: function (stateParams) {
      return 'post-' + stateParams.post + '-tmpl.html';
    }
  });

})

controller('myCtrl', function ($state, $timeout) {
  // go to advanced
  $state.transitionTo('post', {post: 2});
  // after 500ms switch to basic
  $timeout(function() {
      $state.transitionTo('post.basic', {post: 2});
  }, 500)
}

Why would you want to have two different views mapped on the same url. 为什么要在同一个URL上映射两个不同的视图。 Did you imagined the problem when the user would want to add a bookmark on one of the states? 当用户想要在其中一个状态上添加书签时,您是否想过这个问题? How would you then know which one was if they have exactly the same url? 如果他们有完全相同的网址,您怎么知道哪一个?

I would suggest defining two different states like: 我建议定义两个不同的状态,如:

  • /:post - for the simple view /:post - 用于简单视图
  • /:post/advanced - for the advanced view /:post / advanced - 用于高级视图

This can be done with defining /:post as abstract state and two different states for the simple and advanced view. 这可以通过将/:post定义为抽象状态和简单和高级视图的两个不同状态来完成。 For convenience simple view will act as default. 为方便起见,简单视图将作为默认值。 If you like the idea I can provide you an example solution. 如果你喜欢我的想法,我可以为你提供一个示例解决方案。

The other option would be to add url parameter for example: 另一个选项是添加url参数,例如:

  • /:post - for the simple view /:post - 用于简单视图
  • /:post?view=advanced /?:后视=高级

I hope that this answer will help you. 我希望这个答案会对你有所帮助。 At least by seeing the things from different angle ;). 至少从不同的角度看待事物;)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM