如何延迟Angular.js中的路由定义?

时间:2020-12-11 13:21:29

I have configured some basic routes that are available for all users before they log in:

我已经为所有用户配置了一些基本的路由,在他们登录之前都可以使用:

App.config(function ($routeProvider) {
    $routeProvider.
        when('/login', { templateUrl: 'views/login.html', controller: PageStartCtrl.Controller }).
        otherwise({ redirectTo: '/login' });
});

So the only thing user can do is to log in. After the user logs in, I would like to register additional routes like this:

用户唯一能做的就是登录。用户登录后,我想注册其他的路线,如:

$http
  .post('api/Users/Login', {   User: userName, Password: userPassword })
  .success(function (response : any) {
    App.config(function ($routeProvider) {
      $routeProvider
        .when('/dashboard', 
              { templateUrl: 'part/dashboard.html', 
              controller: DashboardCtrl.Controller });
  });

However, I suppose I should call .config method only once, because the $routeProvider is brand new instance that knows nothing about /login route. Further debugging showed me that the first instance of $resourceProvider is used when resolving view change.

但是,我认为我应该只调用.config方法一次,因为$routeProvider是一个完全不知道/登录路径的全新实例。进一步的调试显示,在解析视图更改时使用$resourceProvider的第一个实例。

Q: Is there a way how to register routes later?

问:以后有办法注册路线吗?

Solution from Add routes and templates dynamically to $routeProvider might work, but is quite ugly (involved global variable nastyGlobalReferenceToRouteProvider).

从动态添加路由和模板到$routeProvider的解决方案可能有效,但是非常糟糕(涉及全局变量nastyGlobalReferenceToRouteProvider)。

2 个解决方案

#1


47  

Since routes are defined on a provider level, normally new routes can only be defined in the configuration block. The trouble is that in the configuration block all the vital services are still undefined (most notably $http). So, on the surface it looks like w can't define routes dynamically.

由于路由是在提供者层定义的,所以通常只能在配置块中定义新的路由。问题是,在配置块中,所有重要的服务仍然没有定义(最明显的是$http)。表面上看,w不能动态定义路径。

Now, it turns out that in practice it is quite easy to add / remove routes at any point of the application life-cycle! Looking at the $route source code we can see that all the routes definition are simply kept in the $route.routes hash which can be modified at any point in time like so (simplified example):

实际上,在应用程序生命周期的任何点上添加/删除路由都很容易!查看$route源代码,我们可以看到所有的路由定义都只保存在$route中。路由哈希可以在任意时间点修改(简化示例):

myApp.controller('MyCtrl', function($scope, $route) {    
    $scope.defineRoute = function() {
        $route.routes['/dynamic'] = {templateUrl: 'dynamic.tpl.html'};
    };
});

Here is the jsFiddle that demonstrates this in action: http://jsfiddle.net/4zwdf/6/

下面是演示这一点的jsFiddle: http://jsfiddle.net/4zwdf/6/

In reality, if we want to be close to what AngularJS is doing the route definition logic should be a bit more complex as AngularJS is also defining a redirect route to correctly handle routes with / at the end (make it effectively optional).

实际上,如果我们想要接近AngularJS所做的工作,那么路由定义逻辑应该更复杂一些,因为AngularJS还定义了一个重定向路由,以正确地处理带有/结尾的路由(使其成为有效可选的)。

So, while the above technique will work, we need to note the following:

因此,虽然上述技术将起作用,但我们需要注意以下几点:

  • This technique depends on the internal implementation and might break if the AngularJS team decides to change the way routes are defined / matched.
  • 该技术依赖于内部实现,如果AngularJS团队决定更改路由的定义/匹配方式,则可能会中断。
  • It is also possible to define the otherwise route using the $route.routes as the default route is stored in the same hash under the null key
  • 也可以使用$route定义其他路径。作为默认路由的路由存储在空键下的相同散列中

#2


6  

I found that the answer by @pkozlowski.opensource works only in angularjs 1.0.1. However, after angular-route.js becomes an independent file in the later version, directly set the $route doesn't work.

我发现答案是@pkozlowski。opensource只能在angularjs 1.0.1中工作。然而,angular-route之后。js在以后的版本中成为一个独立的文件,直接设置$route不工作。

After reviewing the code, I find the key of $route.routes is no longer used to match location but $route.route[key].RegExp is used instead. After I copy the origin when and pathRegExp function, route works. See jsfiddle: http://jsfiddle.net/5FUQa/1/

在检查代码之后,我找到了$route的键。路由不再用于匹配位置,而是$route [key]。使用正则表达式。复制了原点when和pathRegExp函数后,route工作。看到jsfiddle:http://jsfiddle.net/5FUQa/1/

  function addRoute(path, route) {
     //slightly modified 'when' function in angular-route.js
  }
  addRoute('/dynamic', {
    templateUrl: 'dynamic.tpl.html'
  });

#1


47  

Since routes are defined on a provider level, normally new routes can only be defined in the configuration block. The trouble is that in the configuration block all the vital services are still undefined (most notably $http). So, on the surface it looks like w can't define routes dynamically.

由于路由是在提供者层定义的,所以通常只能在配置块中定义新的路由。问题是,在配置块中,所有重要的服务仍然没有定义(最明显的是$http)。表面上看,w不能动态定义路径。

Now, it turns out that in practice it is quite easy to add / remove routes at any point of the application life-cycle! Looking at the $route source code we can see that all the routes definition are simply kept in the $route.routes hash which can be modified at any point in time like so (simplified example):

实际上,在应用程序生命周期的任何点上添加/删除路由都很容易!查看$route源代码,我们可以看到所有的路由定义都只保存在$route中。路由哈希可以在任意时间点修改(简化示例):

myApp.controller('MyCtrl', function($scope, $route) {    
    $scope.defineRoute = function() {
        $route.routes['/dynamic'] = {templateUrl: 'dynamic.tpl.html'};
    };
});

Here is the jsFiddle that demonstrates this in action: http://jsfiddle.net/4zwdf/6/

下面是演示这一点的jsFiddle: http://jsfiddle.net/4zwdf/6/

In reality, if we want to be close to what AngularJS is doing the route definition logic should be a bit more complex as AngularJS is also defining a redirect route to correctly handle routes with / at the end (make it effectively optional).

实际上,如果我们想要接近AngularJS所做的工作,那么路由定义逻辑应该更复杂一些,因为AngularJS还定义了一个重定向路由,以正确地处理带有/结尾的路由(使其成为有效可选的)。

So, while the above technique will work, we need to note the following:

因此,虽然上述技术将起作用,但我们需要注意以下几点:

  • This technique depends on the internal implementation and might break if the AngularJS team decides to change the way routes are defined / matched.
  • 该技术依赖于内部实现,如果AngularJS团队决定更改路由的定义/匹配方式,则可能会中断。
  • It is also possible to define the otherwise route using the $route.routes as the default route is stored in the same hash under the null key
  • 也可以使用$route定义其他路径。作为默认路由的路由存储在空键下的相同散列中

#2


6  

I found that the answer by @pkozlowski.opensource works only in angularjs 1.0.1. However, after angular-route.js becomes an independent file in the later version, directly set the $route doesn't work.

我发现答案是@pkozlowski。opensource只能在angularjs 1.0.1中工作。然而,angular-route之后。js在以后的版本中成为一个独立的文件,直接设置$route不工作。

After reviewing the code, I find the key of $route.routes is no longer used to match location but $route.route[key].RegExp is used instead. After I copy the origin when and pathRegExp function, route works. See jsfiddle: http://jsfiddle.net/5FUQa/1/

在检查代码之后,我找到了$route的键。路由不再用于匹配位置,而是$route [key]。使用正则表达式。复制了原点when和pathRegExp函数后,route工作。看到jsfiddle:http://jsfiddle.net/5FUQa/1/

  function addRoute(path, route) {
     //slightly modified 'when' function in angular-route.js
  }
  addRoute('/dynamic', {
    templateUrl: 'dynamic.tpl.html'
  });