我有一个示例MVC6单页应用程序,其中一个视图我想使用ngRoute加载2个Angular部分。您可以在GitHub
查看应用中有3个网址:
路由配置如下:
MVC:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
routes.MapRoute("gamelist", "games", new { controller = "Home", action = "Index"});
routes.MapRoute("gameWithId", "games/2", new { controller = "Home", action = "Index" });
});
角:
myApp.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/games', {
templateUrl: 'partials/gameslist.html',
controller: 'GameController',
controllerAs: 'ctrl'
})
.when('/games/:gameId', {
templateUrl: 'partials/game.html',
controller: 'GameController',
controllerAs: 'ctrl'
});
$locationProvider.html5Mode(true);
}]);
只要我从主页'/'启动应用程序,然后使用页面上的链接导航到部分,这一切都完美无缺。问题是,如果我通过在地址栏中输入应用程序来启动应用程序,则URL#3(localhost / games / 2)不起作用。 URL#2(/ games /)确实有效。
#3不起作用的原因是MVC从URL中删除了'/ games'部分,而Angular得到的只是'/ 2'。如果您运行示例应用程序,您将看到'$ location.path = / 2'。当然,Angular无法使用该路径进行映射,也不会渲染部分。所以我的问题是 - 如何让MVC返回到客户端的完整路径,以便Angular可以映射它?
答案 0 :(得分:1)
您可以使用HTML5模式,只需确保每个请求都映射回您的Index.cshtml视图。此时AngularJS框架加载,客户端路由启动并评估请求URI并加载适当的控制器和视图。
我们使用不同的.cshtml页面在MVC中使用多个Angular应用程序来完成此操作,但我们使用带有通配符的属性路由,例如。
[Route("{*anything}")]
public ActionResult Index()
{
return View("Index");
}
通配符运算符(*)告诉路由引擎URI的其余部分应与任何参数匹配。
我还没有机会掌握MVC6,但我认为你可以用" new"来做这样的事情。属性路由的版本?
[HttpGet("{*anything:regex(^(.*)?$)}"]
public ActionResult Index()
{
return View("Index");
}
答案 1 :(得分:0)
要使#3链接在浏览器的地址栏中运行,我关闭了#34; html5Mode"在Angular和链接#-based。
答案 2 :(得分:0)
我认为这是一个更好的解决方案。
他的解决方案是重写不适合任何路线的请求,并且没有对角度着陆页进行任何扩展。
这是代码。
public class Startup { public void Configure(IApplicationBuilder app, IApplicationEnvironment environment) { // Route all unknown requests to app root app.Use(async (context, next) => { await next(); // If there's no available file and the request doesn't contain an extension, we're probably trying to access a page. // Rewrite request to use app root if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value)) { context.Request.Path = "/app/index.html"; // Put your Angular root page here await next(); } }); // Serve wwwroot as root app.UseFileServer(); // Serve /node_modules as a separate root (for packages that use other npm modules client side) app.UseFileServer(new FileServerOptions() { // Set root of file server FileProvider = new PhysicalFileProvider(Path.Combine(environment.ApplicationBasePath, "node_modules")), // Only react to requests that match this path RequestPath = "/node_modules", // Don't expose file system EnableDirectoryBrowsing = false }); } }