5

在设置所有路由之前,有什么方法可以让服务器命中以检索数据$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

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

4

4 回答 4

8

这是 100% 有效的解决方案!

  1. 准备好你的路线。它们在 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"}}
    
  2. 首先,您必须对 RouteProvider 进行全局引用

      var $routeProviderReference;
     var app = angular.module('myApp', []);
    
      app.config(['$routeProvider', function($routeProvider) {
      $routeProviderReference = $routeProvider;
      }]);
    
  3. 其次,使用方法 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();
    
    });
    
    }]);
    

有关更多信息,请查看下面的参考http://blog.brunoscopelliti.com/how-to-defer-route-definition-in-an-angularjs-web-app

于 2014-10-21T19:59:35.590 回答
5

没有办法做到这一点。

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

因为在这个阶段服务仍在配置中,服务本身不能用于注入——它们实际上还不存在。

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

所有这一切都是说你不能开始运行你的应用程序,这就是 using$http的意思,直到配置完成。所以没有办法从远程数据定义路由。


对于它的价值,我认为无论如何我都看不到这种动态路线的价值。它们本质上是不可预测的,因为它们是由非静态数据构建的。这将完全破坏可书签性,这是路由的主要目的。

所以我想问你为什么一开始就觉得有必要这样做,然后退后一步,看看这是否真的是理想的方式。

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

于 2013-04-03T06:40:13.230 回答
4

更新: @dnc253 -- angular- detour现在已经准备就绪,我认为您可以使用它来获取从 json 加载的路由。它还没有完整的文档并且没有测试,所以从这个意义上说它肯定是不完整的,但是将 json 合并到路由器的实时实例中已经工作了一段时间。

如果您仍在寻找使用服务器定义路由的方法,您可以阅读有关运行示例的说明,然后在 app.js 中查看第三个示例的mergeJson 调用。反馈会很棒——我现在开始进行真正的文档/测试,所以没有必要告诉我文档很烂而且没有任何测试——我就是那个。:) 如果此功能仍在您的需求列表中,希望这些示例足以让您感到满意

答案的较早部分:如果您只想要一组由服务器使用 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-router。但它只能让您获取一组初始路由,因此虽然它为您提供了数据驱动定义的可能性,但它们仅由客户端加载应用程序时可用的数据驱动。

正如 eazel7 指出的那样,如果您创建自己的服务并在配置时绑定到提供程序,则 可以在运行时访问提供程序。但是,要执行您想做的事情,您需要退出进程来进行 $http 调用,并且使用当前的路由器(库存 Angular 核心和 ui-router),您将无法及时得到答案来填充当有人访问您的网站时,深层链接失败之前的路由器。此外,这两个路由器都使用功能来填充路由“表”,因此在最初配置路由后不适合更新路由。

我正在研究解决这些问题的方法,例如,如果路由器不知道请求的路由,它将尝试在调用回退路由或失败之前从服务器获取它。还将支持检查对已知路线的修改。本质上是带有 AJAX/JSON 接口的延迟路由到服务器。它基于 ui-router,位于https://github.com/afterglowtech/angular-detour。它目前实现了路由的可编辑性,但我还没有完成惰性/服务器通信部分。这是我名单上的下一个。密切关注它,它最终应该会做你正在寻找的东西。

于 2013-05-28T16:09:47.487 回答
2

我认为最简单的方法是稍后解析路由,例如,您可以通过 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();
    });
});
于 2013-05-10T06:26:03.007 回答