在设置$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
做到这一点,但如果我错了,请有人纠正我。如果有一些根本原因导致这种情况无法实现,请解释一下。对此有任何帮助将非常感激。
答案 0 :(得分:7)
这是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();
});
}]);
有关详细信息,请参阅参考文献http://blog.brunoscopelliti.com/how-to-defer-route-definition-in-an-angularjs-web-app
答案 1 :(得分:5)
没有办法做到这一点。
提供商是可配置的服务创建者。它们允许我们提供用于配置其创建的API。可配置性是我们config
块的原因。这些是在服务可用之前使用以配置其创建。因此,您可以将设置传递给分别在创建$routeProvider
和$httpProvider
服务时使用的$route
或$http
。
由于此阶段的服务仍在配置,因此服务本身无法注入 - 它们实际上并不存在。
$routeProvider
允许我们配置路由,这些路由必须在我们的应用程序启动时运行。 在我们的应用程序运行期间,在某个随机点开始路由是没有意义的。
这就是说,在配置完成之前,您无法开始运行应用程序,这就是使用$http
的含义。所以没有办法从远程数据定义路由。
对于它的价值,我认为无论如何我都不会看到这种动态路线的价值;它们本质上是不可预测的,因为它们是根据非静态数据构建的。这将彻底打破书签,这是路由的主要目的。
所以我会问你为什么觉得有必要先做这件事,然后退后一步,看看这是否真的应该是理想的做法。
随意发表评论以引发进一步的讨论。
答案 2 :(得分:4)
更新: @ dnc253 - angular-detour现已准备就绪,我认为您可以使用它来获取从json加载的路由。它还没有完整记录,也没有测试,因此从某种意义上说它肯定不完整,但是将json合并到路由器的实时实例中已经有一段时间了。
如果您仍在寻找使用服务器定义路线的方法,可以read instructions on running the samples然后查看第三个样本的mergeJson call in app.js。反馈会很棒 - 我现在开始使用真正的文档/测试,因此没有必要告诉我文档很糟糕而且没有任何测试 - 我就是那个。 :)如果此功能仍在您的需求列表中,希望样本足以发出吱吱声
答案的较早部分:如果您只想要一个由服务器使用JSON定义的静态路由集,您可以使用类似JQuery的东西来获取之前的路由数据 / em>您配置应用程序。
伪代码:
$.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。它目前实现了路由的可编辑性,但我还没有完成懒惰/服务器通信。这是我列表中的下一个。注意它,它应该最终做你想要的。
答案 3 :(得分: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();
});
});