/
RouteView.cs
90 lines (76 loc) · 3.1 KB
/
RouteView.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Rendering;
namespace Microsoft.AspNetCore.Components
{
/// <summary>
/// Displays the specified page component, rendering it inside its layout
/// and any further nested layouts.
/// </summary>
public class RouteView : IComponent
{
private readonly RenderFragment _renderDelegate;
private readonly RenderFragment _renderPageWithParametersDelegate;
private RenderHandle _renderHandle;
/// <summary>
/// Gets or sets the route data. This determines the page that will be
/// displayed and the parameter values that will be supplied to the page.
/// </summary>
[Parameter]
public RouteData RouteData { get; set; }
/// <summary>
/// Gets or sets the type of a layout to be used if the page does not
/// declare any layout. If specified, the type must implement <see cref="IComponent"/>
/// and accept a parameter named <see cref="LayoutComponentBase.Body"/>.
/// </summary>
[Parameter]
public Type DefaultLayout { get; set; }
public RouteView()
{
// Cache the delegate instances
_renderDelegate = Render;
_renderPageWithParametersDelegate = RenderPageWithParameters;
}
/// <inheritdoc />
public void Attach(RenderHandle renderHandle)
{
_renderHandle = renderHandle;
}
/// <inheritdoc />
public Task SetParametersAsync(ParameterView parameters)
{
parameters.SetParameterProperties(this);
if (RouteData == null)
{
throw new InvalidOperationException($"The {nameof(RouteView)} component requires a non-null value for the parameter {nameof(RouteData)}.");
}
_renderHandle.Render(_renderDelegate);
return Task.CompletedTask;
}
/// <summary>
/// Renders the component.
/// </summary>
/// <param name="builder">The <see cref="RenderTreeBuilder"/>.</param>
protected virtual void Render(RenderTreeBuilder builder)
{
var pageLayoutType = RouteData.PageType.GetCustomAttribute<LayoutAttribute>()?.LayoutType
?? DefaultLayout;
builder.OpenComponent<LayoutView>(0);
builder.AddAttribute(1, nameof(LayoutView.Layout), pageLayoutType);
builder.AddAttribute(2, nameof(LayoutView.ChildContent), _renderPageWithParametersDelegate);
builder.CloseComponent();
}
private void RenderPageWithParameters(RenderTreeBuilder builder)
{
builder.OpenComponent(0, RouteData.PageType);
foreach (var kvp in RouteData.RouteValues)
{
builder.AddAttribute(1, kvp.Key, kvp.Value);
}
builder.CloseComponent();
}
}
}