我想在包装器内渲染一些组件,所以当我有以下剃刀时:
<Component/>
我希望它像这样渲染:
<Wrapper>
<Component />
</Wrapper>
我创建了一个自定义的
IComponentActivator
来完成这项工作,但是当我尝试获取组件的引用时,我得到了 InvalidCastException
。例如
这有效:
<ComponentIWantToBeInWrapper />
这不是
<ComponentIWantToBeInWrapper @ref=_ref />
据我了解,引用捕获尝试获取
ComponentIWantToBeInWrapper
类型的实例,但获取的是 Wrapper
实例,然后抛出错误。
我想知道有没有办法让它发挥作用?是否有可能以某种方式捕获包装器的子组件而不是包装器本身?
ComponentActivator.cs
public class ComponentActivator : IComponentActivator
{
public IComponent CreateInstance(Type componentType)
{
if(componentType == typeof(Component))
{
return (IComponent)Activator.CreateInstance(typeof(DivWrapper<>).MakeGenericType(componentType))!;
}
if (componentType.IsGenericType && componentType.GetGenericTypeDefinition() == typeof(Dummy<>))
{
var innerType = componentType.GetGenericArguments()[0];
return (IComponent)Activator.CreateInstance(innerType)!;
}
return (IComponent)Activator.CreateInstance(componentType)!;
}
}
DivWrapper.razor
@typeparam T where T : ComponentBase
<div style="border: 1px solid red">
<Dummy T="T" @attributes=Attrs />
</div>
@code {
[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> Attrs { get; set; } = default!;
}
虚拟.cs
public class Dummy<T> : ComponentBase where T : ComponentBase
{
}
Page.razor
@page "/"
<Component />
@* <Component @ref=_ref /> this will crush an app *@
你需要考虑你在做什么。
在您的
Page
中,您将声明如下内容:
private MyComponent? _ref;
这是 Razor,将被编译到 Razor 编译器构建的组件类中。
在运行时,您的
ComponentActivator
正在将组件更改为 MyReplacementComponent
。
在您的场景中,
MyReplacementComponent
和MyComponent
没有关系。运行时无法抛出异常并崩溃。
但是,如果
MyReplacementComponent
继承自 MyComponent
那么它将起作用。
令我感兴趣的是,这个功能实际上是公开的。您可以用它编写很多越界代码,从而真正搞砸事情!
你确定用更主流的技术不能做你想做的事吗?