捕获对动态添加的包装器内组件的引用

问题描述 投票:0回答:1

我想在包装器内渲染一些组件,所以当我有以下剃刀时:

<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 *@
c# blazor
1个回答
0
投票

你需要考虑你在做什么。

在您的

Page
中,您将声明如下内容:

    private MyComponent? _ref;

这是 Razor,将被编译到 Razor 编译器构建的组件类中。

在运行时,您的

ComponentActivator
正在将组件更改为
MyReplacementComponent

在您的场景中,

MyReplacementComponent
MyComponent
没有关系。运行时无法抛出异常并崩溃。

但是,如果

MyReplacementComponent
继承自
MyComponent
那么它将起作用。

令我感兴趣的是,这个功能实际上是公开的。您可以用它编写很多越界代码,从而真正搞砸事情!

你确定用更主流的技术不能做你想做的事吗?

© www.soinside.com 2019 - 2024. All rights reserved.