mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-11-30 02:58:13 +08:00
docs: add convention router
This commit is contained in:
parent
add9e58de3
commit
8ca44d2ce5
@ -13,5 +13,5 @@ An enterprise-class UI components based on Ant Design and Blazor.
|
||||
![](https://img.shields.io/github/workflow/status/elderjames/ant-design-blazor/Publish%20Docs?style=flat-square)
|
||||
[![AntBlazor](https://img.shields.io/nuget/v/AntBlazor.svg?color=red&style=flat-square)](https://www.nuget.org/packages/AntBlazor/)
|
||||
[![AntBlazor](https://img.shields.io/nuget/dt/AntBlazor.svg?style=flat-square)](https://www.nuget.org/packages/AntBlazor/)
|
||||
[![AntBlazor](https://img.shields.io/github/license/ElderJames/ant-design-blazor?color=blue&style=flat-square)]()
|
||||
[![AntBlazor](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](https://github.com/ElderJames/ant-design-blazor/blob/master/LICENSE)
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@ namespace AntBlazor.Docs.ClientApp
|
||||
builder.RootComponents.Add<App>("app");
|
||||
|
||||
builder.Services.AddBaseAddressHttpClient();
|
||||
builder.Services.AddAntBlazor();
|
||||
builder.Services.AddAntBlazorDocs();
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace AntBlazor.Docs.ServerApp
|
||||
{
|
||||
services.AddRazorPages();
|
||||
services.AddServerSideBlazor();
|
||||
services.AddAntBlazor();
|
||||
services.AddAntBlazorDocs();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -1,4 +1,4 @@
|
||||
<Router AppAssembly="@typeof(MainLayout).Assembly">
|
||||
<ConventionRouter>
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
</Found>
|
||||
@ -7,4 +7,4 @@
|
||||
<p>Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
</ConventionRouter>
|
@ -1,5 +1,4 @@
|
||||
@page "/avatar"
|
||||
|
||||
|
||||
<h3>Avatar</h3>
|
||||
<AntAvatar size="large" icon="user" />
|
||||
<AntAvatar icon="user" />
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/breadcrumb"
|
||||
|
||||
|
||||
<h3>Breadcrumb</h3>
|
||||
|
||||
<h4>simple</h4>
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/button"
|
||||
|
||||
|
||||
<AntTitle level="1">Button 按钮</AntTitle>
|
||||
<AntText>按钮用于开始一个即时操作</AntText>
|
||||
<AntTitle level="2">何时使用</AntTitle>
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/card"
|
||||
|
||||
|
||||
<h3>Actions Card</h3>
|
||||
<AntCard bordered Actions="new[] { actionSetting,actionEdit,actionEllipsis}" avatar="avatarTemplate">
|
||||
<Title>Card</Title>
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/divider"
|
||||
|
||||
|
||||
<h3>Divider</h3>
|
||||
|
||||
<h3>Horizontal</h3>
|
||||
|
@ -1,4 +1,4 @@
|
||||
@page "/docs/{fileName}"
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
|
||||
<Markdown>
|
||||
|
@ -1,6 +1,4 @@
|
||||
@page "/error"
|
||||
|
||||
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
@page "/icon"
|
||||
|
||||
|
||||
|
||||
<DemoCard>
|
||||
<Title>基本使用</Title>
|
||||
<Description>
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/"
|
||||
|
||||
|
||||
<Markdown>
|
||||
<p align="center">
|
||||
<a href="https://yangshunjie.com/ant-design-blazor/">
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/switch"
|
||||
|
||||
|
||||
<h1>Switch开关</h1>
|
||||
<p>开关选择器。</p>
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
@page "/tag"
|
||||
|
||||
|
||||
|
||||
<h3>Basic Tag</h3>
|
||||
<AntTag>Tag 1</AntTag>
|
||||
<AntTag>
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/timeline"
|
||||
|
||||
|
||||
<h3>Timeline</h3>
|
||||
|
||||
<AntTimeline mode="alternate" >
|
||||
|
@ -1,5 +1,4 @@
|
||||
@page "/typography"
|
||||
|
||||
|
||||
<h1>Typography 排版</h1>
|
||||
<p>文本的基本格式</p>
|
||||
|
||||
|
114
site/AntBlazor.Docs/Routing/ConventionRouter.cs
Normal file
114
site/AntBlazor.Docs/Routing/ConventionRouter.cs
Normal file
@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
|
||||
namespace AntBlazor.Docs.Routing
|
||||
{
|
||||
public class ConventionRouter : IComponent, IHandleAfterRender, IDisposable
|
||||
{
|
||||
private RenderHandle _renderHandle;
|
||||
private bool _navigationInterceptionEnabled;
|
||||
private string _location;
|
||||
|
||||
[Inject] private NavigationManager NavigationManager { get; set; }
|
||||
[Inject] private INavigationInterception NavigationInterception { get; set; }
|
||||
[Inject] private RouteManager RouteManager { get; set; }
|
||||
|
||||
[Parameter] public RenderFragment NotFound { get; set; }
|
||||
[Parameter] public RenderFragment<RouteData> Found { get; set; }
|
||||
|
||||
public void Attach(RenderHandle renderHandle)
|
||||
{
|
||||
_renderHandle = renderHandle;
|
||||
_location = NavigationManager.Uri;
|
||||
NavigationManager.LocationChanged += HandleLocationChanged;
|
||||
}
|
||||
|
||||
public Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
parameters.SetParameterProperties(this);
|
||||
|
||||
if (Found == null)
|
||||
{
|
||||
throw new InvalidOperationException($"The {nameof(ConventionRouter)} component requires a value for the parameter {nameof(Found)}.");
|
||||
}
|
||||
|
||||
if (NotFound == null)
|
||||
{
|
||||
throw new InvalidOperationException($"The {nameof(ConventionRouter)} component requires a value for the parameter {nameof(NotFound)}.");
|
||||
}
|
||||
|
||||
RouteManager.Initialise();
|
||||
Refresh();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task OnAfterRenderAsync()
|
||||
{
|
||||
if (!_navigationInterceptionEnabled)
|
||||
{
|
||||
_navigationInterceptionEnabled = true;
|
||||
return NavigationInterception.EnableNavigationInterceptionAsync();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
NavigationManager.LocationChanged -= HandleLocationChanged;
|
||||
}
|
||||
|
||||
private void HandleLocationChanged(object sender, LocationChangedEventArgs args)
|
||||
{
|
||||
_location = args.Location;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
var relativeUri = NavigationManager.ToBaseRelativePath(_location);
|
||||
var parameters = ParseQueryString(relativeUri);
|
||||
|
||||
if (relativeUri.IndexOf('?') > -1)
|
||||
{
|
||||
relativeUri = relativeUri.Substring(0, relativeUri.IndexOf('?'));
|
||||
}
|
||||
|
||||
var segments = relativeUri.Trim().Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
var matchResult = RouteManager.Match(segments);
|
||||
|
||||
if (matchResult.IsMatch)
|
||||
{
|
||||
var routeData = new RouteData(
|
||||
matchResult.MatchedRoute.Handler,
|
||||
parameters);
|
||||
|
||||
_renderHandle.Render(Found(routeData));
|
||||
}
|
||||
else
|
||||
{
|
||||
_renderHandle.Render(NotFound);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, object> ParseQueryString(string uri)
|
||||
{
|
||||
var querystring = new Dictionary<string, object>();
|
||||
|
||||
foreach (string kvp in uri.Substring(uri.IndexOf("?") + 1).Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (kvp != "" && kvp.Contains("="))
|
||||
{
|
||||
var pair = kvp.Split('=');
|
||||
querystring.Add(pair[0], pair[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return querystring;
|
||||
}
|
||||
}
|
||||
}
|
24
site/AntBlazor.Docs/Routing/MatchResult.cs
Normal file
24
site/AntBlazor.Docs/Routing/MatchResult.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace AntBlazor.Docs.Routing
|
||||
{
|
||||
public class MatchResult
|
||||
{
|
||||
public bool IsMatch { get; set; }
|
||||
public Route MatchedRoute { get; set; }
|
||||
|
||||
public MatchResult(bool isMatch, Route matchedRoute)
|
||||
{
|
||||
IsMatch = isMatch;
|
||||
MatchedRoute = matchedRoute;
|
||||
}
|
||||
|
||||
public static MatchResult Match(Route matchedRoute)
|
||||
{
|
||||
return new MatchResult(true, matchedRoute);
|
||||
}
|
||||
|
||||
public static MatchResult NoMatch()
|
||||
{
|
||||
return new MatchResult(false, null);
|
||||
}
|
||||
}
|
||||
}
|
28
site/AntBlazor.Docs/Routing/Route.cs
Normal file
28
site/AntBlazor.Docs/Routing/Route.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace AntBlazor.Docs.Routing
|
||||
{
|
||||
public class Route
|
||||
{
|
||||
public string[] UriSegments { get; set; }
|
||||
public Type Handler { get; set; }
|
||||
|
||||
public MatchResult Match(string[] segments)
|
||||
{
|
||||
if (segments.Length != UriSegments.Length)
|
||||
{
|
||||
return MatchResult.NoMatch();
|
||||
}
|
||||
|
||||
for (var i = 0; i < UriSegments.Length; i++)
|
||||
{
|
||||
if (string.Compare(segments[i], UriSegments[i], StringComparison.OrdinalIgnoreCase) != 0)
|
||||
{
|
||||
return MatchResult.NoMatch();
|
||||
}
|
||||
}
|
||||
|
||||
return MatchResult.Match(this);
|
||||
}
|
||||
}
|
||||
}
|
59
site/AntBlazor.Docs/Routing/RouteManager.cs
Normal file
59
site/AntBlazor.Docs/Routing/RouteManager.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AntBlazor.Docs.Routing
|
||||
{
|
||||
public class RouteManager
|
||||
{
|
||||
public Route[] Routes { get; private set; }
|
||||
|
||||
public void Initialise()
|
||||
{
|
||||
var pageComponentTypes = Assembly.GetExecutingAssembly()
|
||||
.ExportedTypes
|
||||
.Where(t => t.Namespace != null && (t.IsSubclassOf(typeof(ComponentBase))
|
||||
&& t.Namespace.Contains(".Pages")));
|
||||
|
||||
var routesList = new List<Route>();
|
||||
foreach (var pageType in pageComponentTypes)
|
||||
{
|
||||
if (pageType.FullName == null)
|
||||
continue;
|
||||
|
||||
var newRoute = new Route
|
||||
{
|
||||
UriSegments = pageType.FullName.Substring(pageType.FullName.IndexOf("Pages", StringComparison.Ordinal) + 6).Split('.'),
|
||||
Handler = pageType
|
||||
};
|
||||
|
||||
routesList.Add(newRoute);
|
||||
}
|
||||
|
||||
Routes = routesList.ToArray();
|
||||
}
|
||||
|
||||
public MatchResult Match(string[] segments)
|
||||
{
|
||||
if (segments.Length == 0)
|
||||
{
|
||||
var indexRoute = Routes.SingleOrDefault(x => x.Handler.FullName != null && x.Handler.FullName.ToLower().EndsWith("index"));
|
||||
return MatchResult.Match(indexRoute);
|
||||
}
|
||||
|
||||
foreach (var route in Routes)
|
||||
{
|
||||
var matchResult = route.Match(segments);
|
||||
|
||||
if (matchResult.IsMatch)
|
||||
{
|
||||
return matchResult;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchResult.NoMatch();
|
||||
}
|
||||
}
|
||||
}
|
16
site/AntBlazor.Docs/ServiceCollectionExtensions.cs
Normal file
16
site/AntBlazor.Docs/ServiceCollectionExtensions.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using AntBlazor.Docs.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AntBlazor.Docs
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddAntBlazorDocs(this IServiceCollection services)
|
||||
{
|
||||
services.AddAntBlazor();
|
||||
services.AddSingleton<RouteManager>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.JSInterop
|
||||
@using AntBlazor
|
||||
@using AntBlazor.Docs.Pages
|
||||
@using AntBlazor.Docs.Shared
|
||||
@using AntBlazor
|
||||
@using AntBlazor.Docs.Routing
|
||||
@using AntBlazor.Docs.Shared
|
Loading…
Reference in New Issue
Block a user