【问题标题】:Blazor - Get object set by parentBlazor - 获取由父级设置的对象
【发布时间】:2021-12-10 20:48:07
【问题描述】:

我有以下代码:

@page "somePage"

<TeamsApplication RequireAuthentication="true">
    <ApplicationTemplate Context="context">
        Some HTML...
        @*context works here*@
    </ApplicationTemplate>
</TeamsApplication>

@code{
  //context doesnt work here
}

在 ApplicationTemplate 标记内,我可以访问上下文对象实例,但不能在代码部分进行。有没有办法可以访问该实例及其值?

【问题讨论】:

  • 我确实回复了这个,但重新阅读我不确定它是否正确。为什么不能从ApplicationTemplate 代码访问Context 属性?它应该是代码中的[Parameter]??
  • 如果不清楚,我很抱歉。显示的代码不是来自 ApplicationTemplate 组件。相反,来自包装在 ApplicationTemplate 中的其他组件。在 ApplicationTemplate 组件中正确设置了参数。
  • 属性级联向下,而不是向上-因此在此处设置上下文属性将不起作用。我会在答案中提出一种方法

标签: c# .net blazor


【解决方案1】:

一个熟悉的问题,从一组想要共享数据和状态的组件构建一个页面。您可以将它们全部连接在一起,但很快就会变成意大利面条。

解决方案是将数据和状态与 UI 分开。 UI 代码保留在组件中,数据和状态存在于服务中 - 通常称为 ViewService。该服务通常是有范围的,即每个 SPA 会话一个。每个组件都注入服务,然后访问共享数据/状态。您使用服务中的事件来通知组件他们需要做出反应的更改 - 通常是重新渲染。

在您的问题中,该服务将持有context。然后TeamsApplicationApplicationTemplateSomePage 和任何其他组件都会注入服务并访问context

如果你想要一个有效的例子,请问,我会在这个答案中添加一个。

【讨论】:

    【解决方案2】:

    属性通常向下流动,而不是向上流动。所以Context 属性不会那样工作。我能想到的最简单的解决方案是 EventCallback,以便 ApplicationTemplate 向父级发送一条消息,说明 Context 可用

    ApplicationTemplate.razor

    
        [Parameter] public EventCallback<Context> ContextChanged {  get;  set; }
    
        /// <summary>
        /// Context was set from somewhere
        /// </summary>
        async Task ContextSet(Context newValue)
        {
            // notify anyone listening to ContextChanged
            await ContextChanged.InvokeAsync(newValue);
        }
    

    然后在你的页面逻辑中你监听这个事件回调:

    
    <TeamsApplication>
        <ApplicationTemplate ContextChanged=HandleContextChanged>
            @* todo *@
        </ApplicationTemplate>
    
    </TeamsApplication>
    
    @code
    {
        /// <summary>
        /// Handle event from ApplicationTemplate
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        async Task HandleContextChanged(Context context)
        {
            // context is now available
            
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      您可以创建一个函数,该函数接受与您的上下文类型相同类型的参数,因此您可以在该函数中访问,但问题是:您需要该上下文做什么?

      如果您需要创建一个需要访问该上下文的自定义组件,请将其传递给另一个子组件,然后创建一个 RenderFragment 类型的 [Parameter] 以便您可以随意处理它。

      您甚至可以创建一个呈现 RenderFragment 的本地函数,但此类内容的 Razor 语法相当笨拙且有点错误

      例如我有这样的方法

      public RenderFragment DefaultActionTemplate(PanelAction action) =>@:@{
            if (action.IsToggle) {
               <div>Toggle</div>
            }
            else {
               <div>Button</div>
            }
         }
         ;
      

      你也可以这样做,用你的上下文类型代替我的PanelAction,概念是一样的

      正如我告诉你的那样,语法很尴尬,你在最后看到的分号需要换行,不能在最后的花括号旁边 看到这个问题:https://github.com/dotnet/aspnetcore/issues/11612

      【讨论】:

        猜你喜欢
        • 2011-02-28
        • 2021-08-23
        • 2010-11-14
        • 2021-11-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        • 2020-02-15
        • 2019-01-10
        相关资源
        最近更新 更多