AngularJS中的动态路由-我可以在设置$routeProvider之前从服务器检索数据吗?

AngularJS中的动态路由-我可以在设置$routeProvider之前从服务器检索数据吗?,angularjs,angularjs-routing,Angularjs,Angularjs Routing,在$routeProvider上设置所有路由之前,是否有任何方法使服务器点击以检索数据?我希望能够基于此远程数据动态设置路由。我试过这样的方法: angular.module("myApp").config(["$routeProvider", "$http", function($routeProvider, $http) { $http.get("myData").success(function(data) { $routeProvider.when(data.dy

$routeProvider
上设置所有路由之前,是否有任何方法使服务器点击以检索数据?我希望能够基于此远程数据动态设置路由。我试过这样的方法:

angular.module("myApp").config(["$routeProvider", "$http", function($routeProvider, $http) {
    $http.get("myData").success(function(data) {
        $routeProvider.when(data.dynamicRoute, {
            //route definition
        }
        //or
        $routeProvider.when("/known/route", {
            redirectTo: data.dynamicRoute
        }
    });
}]);
但这会导致以下错误:

Unknown provider: $http from myApp

因此,我知道config函数是注入提供者而不是服务。然而,我仍然想知道我是否能以某种方式实现我的最终目标?我不认为我能用
$httpProvider
做到这一点,但如果我错了,请有人纠正我。如果有什么根本原因导致这不可能,请解释。在此方面的任何帮助都将不胜感激。

没有办法做到这一点

提供者是可配置的服务创建者。它们允许我们提供用于配置其创建的API。可配置性将我们带到
config
块。这些在服务可用之前使用,以便配置其创建。因此,您可以将设置传递给
$routeProvider
$httpProvider
,它将分别在创建
$route
$http
服务时使用这些设置

因为服务仍在这个阶段进行配置,所以服务本身不可用于注入-它们实际上还不存在

$routeProvider
允许我们配置应用程序启动时必须运行的路由。在应用程序运行期间,让路由在某个随机点启动是没有意义的

所有这些都意味着,在配置完成之前,您无法开始运行应用程序,这就是使用
$http
的意思。因此,无法从远程数据定义路由


不管它值多少钱,我认为我看不到这种动态路线的价值;它们本质上是不可预测的,因为它们是由非静态数据构建的。这将彻底破坏作为路由主要目的的书签功能

所以我想问你,为什么你首先觉得有必要这样做,然后退一步,看看这是否真的是理想的做法


请随意发表评论以引发进一步讨论。

我认为最简单的方法是稍后解析路由,例如,您可以通过json询问路由。请注意,我在配置阶段通过$provide使用$routeProvider创建了一个工厂,这样我就可以在运行阶段甚至在控制器中继续使用$routeProvider对象

'use strict';

angular.module('myapp', []).config(function($provide, $routeProvider) {
    $provide.factory('$routeProvider', function () {
        return $routeProvider;
    });
}).run(function($routeProvider, $http) {
    $routeProvider.when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
    }).otherwise({
        redirectTo: '/'
    });

    $http.get('/dynamic-routes.json').success(function(data) {
        $routeProvider.when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl'
        });
        // you might need to call $route.reload() if the route changed
        $route.reload();
    });
});

更新:@dnc253——现在已经准备好了,我认为您可以使用它从json加载路由。它还没有很好的文档记录,也没有测试,所以从这个意义上说它肯定不完整,但是将json合并到路由器的一个活动实例中已经有一段时间了

如果您仍在寻找使用服务器定义的路由的方法,那么您可以查看第三个示例。反馈会很好——我现在正在开始真正的文档/测试,所以没有必要告诉我文档很糟糕,而且没有任何测试——我正在做这件事。:)如果此功能仍在您的需求列表中,希望这些示例足以满足您的需求

答案的老部分:如果您只需要服务器用JSON定义的一组静态路由,您可以在配置应用程序之前使用JQuery之类的工具获取路由数据

伪代码:

$.ajax({
  url: "http://example.com/routes"
  }
}).done(function ( data ) {
    angular
        .module('myApp',[])
        .config(function($routeProvider) {
          //read routing instructions from data and call "when" on $routeProvider to define the routes
         });

});
这也适用于ui路由器。但它只允许您获取一组初始路由,因此虽然它提供了数据驱动定义的可能性,但它们仅由客户端加载应用程序时可用的数据驱动

正如eazel7所指出的,如果您在配置时创建自己的绑定到提供者的服务,则可以在运行时访问提供者然而,要想做你想做的事情,你需要在进程外进行$http呼叫,而使用当前路由器(库存Angular core和ui路由器),在有人访问你的站点时深度链接失败之前,你无法及时得到答案来填充路由器。此外,这两个路由器都使用函数来填充路由“表”,因此不适合在初始配置后更新路由


我正在研究解决这些问题的方法,例如,如果路由器不知道请求的路由,它将尝试在调用回退路由或失败之前从服务器获取它。还将支持检查对已知路线的修改。基本上是惰性路由,使用AJAX/JSON接口连接到服务器。它是基于用户界面路由器,并生活在。它目前实现了路由的可编辑性,但我还没有完成惰性/服务器通信部分。这是我名单上的下一个。密切关注它,它应该会完成你想要的任务。

这是100%有效的解决方案

  • 准备好你的路线。它们在json中可能看起来像这样

    {"0":{"id":1,"when":"/","controller":"MainController","template":"app/views/site/main_inner.html"},"1":{"id":2,"when":"/firm/:firmID","controller":"CompanyController","template":"app/views/site/firm.html"},"2":{"id":3,"when":"/search","controller":"SearchController","template":"app/views/site/search.html"}}
    
  • 首先,您必须对RouteProvider进行全局引用

      var $routeProviderReference;
     var app = angular.module('myApp', []);
    
      app.config(['$routeProvider', function($routeProvider) {
      $routeProviderReference = $routeProvider;
      }]);
    
  • 其次,使用run方法对路由执行ajax调用

       app.run(['$rootScope', '$http', '$route', function($rootScope, $http, $route) {
        //getting routes
        $http.get('routes.php').success(function (data) {
    
        angular.forEach(data, function (route) {
            $routeProviderReference.when( route.when, { templateUrl: route.template, controller: route.controller } );
        });
        $routeProviderReference.otherwise({ redirectTo: '/' });
        $route.reload();
    
    });
    
    }]);
    

  • 有关更多信息,请参阅下面的参考资料

    唯一的方法是编写您自己的自定义指令,并使用$location service而不是$routeProvider。您可以使用
    中的
    resolve
    来发出请求,以便在您的请求完成之前,不会进行任何其他操作completed@Ajaybeni-他必须重写$route服务也是。@charlietfl-他在设置路由之前需要数据,所以解决方案不起作用。@josh…只是在那里尝试一下……是的,这是操作代码的编写方式,但可能不是所需的。谢谢您的解释。基本上,