【问题标题】:Passing parameters to a Blazor component将参数传递给 Blazor 组件
【发布时间】:2021-01-18 20:35:30
【问题描述】:

我想不出如何实现以下目标:

我需要将参数集合(或数组)传递给我的 Blazor 组件。传递的参数是 Blazor 组件。参数集合必须作为嵌套标记传递。需要能够单独调用每个传递的参数组件的渲染。

也就是说,我想要这样的东西:

<MyComponent>
  <ParameterCollection>
    <MyParameterComponent1>Caption1</MyParameterComponent1>
    <MyParameterComponent2>Caption2</MyParameterComponent2>
    <MyParameterComponent3>Caption3</MyParameterComponent3>
  </ParameterCollection>
</MyComponent>

我的组件代码:

@code{
    [Parameter]
    public RenderFragment[] ParameterCollection {get; set;} //Runtime error
}

我想得到的显然是在这里实现的commercial Blazor component(选择查看源标签)。 向 GridColumns 参数传递 GridColumn 组件的集合。更准确地说,我认为,它是它们对应的 RenderFragments 的集合。 问题是它是怎么做的?

【问题讨论】:

    标签: c# asp.net-core blazor blazor-server-side blazor-client-side


    【解决方案1】:

    Blazor 无法获取渲染片段的集合作为参数。这里有两种不同的方法可以将动态组件计数作为参数传递

    1. 如果您只想传递多个组件,但可以按照传递它们的顺序呈现它们:
    <MyComponent>
        <ParameterCollection>
            <MyParameterComponent1>Caption1</MyParameterComponent1>
            <MyParameterComponent2>Caption2</MyParameterComponent2>
            <MyParameterComponent3>Caption3</MyParameterComponent3>
        </ParameterCollection>
    </MyComponent>
    
    @code{
        [Parameter]
        public RenderFragment ParameterCollection {get; set;} 
    }
    

    您可以将它们渲染为将@ParameterCollection 放置在您的.razor 文件中的任何位置。

    这是这种方法的一个工作示例:https://blazorrepl.com/repl/QaFEadlQ52kWHVkX13

    1. 当您希望同时计算两个动态组件并控制它们的放置位置时。

    在这种方法中,您仅使用组件来传递一些元数据 - 类似于 @Henk Holterman 的建议:

    <MyComponent>
        <ParameterCollection>
            <MyParameterComponent1>Caption1</MyParameterComponent1>
            <MyParameterComponent2>Caption2</MyParameterComponent2>
            <MyParameterComponent3>Caption3</MyParameterComponent3>
        </ParameterCollection>
    </MyComponent>
    
    @code{
        [Parameter]
        public RenderFragment ParameterCollection {get; set;} 
    }
    

    通过这种方式,您只需将@ParameterCollection 放在您的.razor 文件的开头,该文件包含在Parent 组件的CascadingValue 中。这将触发所有子组件的渲染。

    在每个组件的初始化中,您需要触发向父级填充元数据:

    @code {
        [CascadingParameter]
        private MyComponent Parent { get; set; }
        protected override void OnInitialized()
        {
            if (Parent != null)  Parent.AddChild(this);    
        }
    }
    

    收到元数据后,只需要再次触发渲染,并在

    中使用该数据

    这是一个工作示例:https://blazorrepl.com/repl/wuPOOxvd06vFcWFG21

    【讨论】:

    • 谢谢。 1分不是我的情况。我查看了您提到的链接中的代码。在 Parent 组件中,你渲染了 Child 组件的单个参数,但是如何渲染整个 Child 组件及其相关参数呢?
    • 我发现这篇文章展示了如何从它的实例渲染组件:mikaelkoskinen.net/post/render-razor-component-instance-blazor。虽然我不确定你为什么要这样做。
    【解决方案2】:

    反过来:DatagGridColumnCollection 组件将自身作为 CascadingValue 插入,而 DatagGridColumn 组件只需调用 Add 方法。

    列集合

    <CascadingValue Value="this">
      @ChildContent
    </CascadingValue>
    
    @code
    { 
        public void Add(DataGridColumn colum) { ... }
    }
    

    数据网格列

    @code {
      [CascadingParameter]
      private ColumnCollection Parent { get; set; }
      protected override void OnInitialized()
      {
        if (Parent != null)  Parent.Add(this);    
      }
    }
    

    【讨论】:

    • 感谢您的回复。我已经尝试过您提到的方式(组件向父集合注册自身)但是......如何调用 DataGridColumn 实例的渲染并为其分配参数。
    • 好吧,我想一个 Column 有一个 Header 模板和一个 Cell 模板(RenderFragments)。所以 foreach() 循环应该可以工作。
    • 嗯...是的,你说得对。为此,我将创建一个 TemplateHolder 组件。我想知道为什么框架的创建者没有提供从 ComponentBase 的后代实例呈现组件的简单可能性。
    • 我认为他们做到了。不确定你真正想要什么,但这一切都是可行的。制作 DataGrid 或 TabControl 比在我知道的任何其他框架中更容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2022-08-19
    相关资源
    最近更新 更多