如何在同一 Blazor 页面上的 Razor 组件之间传递数据?

Hal*_*ich 9 components parameter-passing razor blazor asp.net-core-3.0

我有这个 Blazor 页面

@page "/bearoffdata"
@using BlazorBoinq.Components

<h3>Bearoff Data</h3>

<Position_Hex_IdPair />

<PositionData />

@code {

}
Run Code Online (Sandbox Code Playgroud)

使用这两个 Razor 组件:

@using BlazorBoinq.Data
@using BgBearoffCoreNamespace;
@inject BgBearoffService BoService

<label>Position</label>

<input type="text" spellcheck="false" @bind-value="@PositionText" @bind-value:event="oninput" />

<span> = </span>

<input type="number" step="1" @bind-value="@PositionId" @bind-value:event="oninput" />

<label>Id</label>

@code {

    BgBearoffCore BgBo;

    protected override async Task OnInitializedAsync()
    {
        BgBo = await BoService.GetBgBearoffAsync();
    }

    private Int64 positionId;
    private String positionText;

    protected Int64 PositionId
    {
        get => positionId;
        set
        {
            positionId = value;
            if (positionId > 0 && positionId <= BgBo.MaxId)
            {
                positionText = BgBearoffCore.menOnPointToHexString(BgBo.getMenOnPointFromInvariantId(positionId));
            }
            else
                positionText = "";
        }
    }

    protected String PositionText
    {
        get => positionText;
        set
        {
            positionText = value;
            if (BgBo.IsValidHexPosition(positionText))
                positionId = BgBo.getInvariantIdFromPosition(positionText);
            else
                positionId = 0;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

@using BlazorBoinq.Data
@using BgBearoffCoreNamespace;
@inject BgBearoffService BoService

<button class="btn btn-primary" @onclick="ShowBearoffInfo">Show Data</button>

<br>

<textarea cols="36" rows="36" readonly @bind="@BearoffInfo" />


@code {
    BgBearoffCore BgBo;

    protected override async Task OnInitializedAsync()
    {
        BgBo = await BoService.GetBgBearoffAsync();
    }


    private String bearoffInfo = "";
    public String BearoffInfo
    {
        get => bearoffInfo;
        set { }
    }
    protected void ShowBearoffInfo()
    {
        bearoffInfo = BgBo.getPositionInformationText(86);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想PositionId将第一个组件的 传递给第二个组件,因此我可以用参数替换最后一行中的硬编码 86 PositionId。当我尝试发布此内容时出现错误

看起来您的帖子主要是代码;请添加更多详细信息。

我不确定要添加哪些细节可以帮助某人回答这个问题。

Mic*_*ton 8

是的,您有两个不直接相关的控件,因此您不能简单地传递参数。

两种选择:

级联参数:https : //docs.microsoft.com/en-us/aspnet/core/blazor/components? view = aspnetcore-3.0#cascading-values-and-parameters

或状态管理。对于状态管理,这可能会有所帮助: 在 Blazor 中实施状态管理

你有一个这样的类:

using System;
public class CounterState
{
    // _currentCount holds the current counter value
    // for the entire application
    private int _currentCount = 0;
    // StateChanged is an event handler other pages
    // can subscribe to 
    public event EventHandler StateChanged;
    // This method will always return the current count
    public int GetCurrentCount()
    {
        return _currentCount;
    }
    // This method will be called to update the current count
    public void SetCurrentCount(int paramCount)
    {
        _currentCount = paramCount;
        StateHasChanged();
    }
    // This method will allow us to reset the current count
    public void ResetCurrentCount()
    {
        _currentCount = 0;
        StateHasChanged();
    }
    private void StateHasChanged()
    {
        // This will update any subscribers
        // that the counter state has changed
        // so they can update themselves
        // and show the current counter value
        StateChanged?.Invoke(this, EventArgs.Empty);
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以像这样在 startup.cs 文件中注册它:

services.AddScoped<CounterState>();
Run Code Online (Sandbox Code Playgroud)

您在每个 .razor 控件中引用它,如下所示:

@inject CounterState CounterState
Run Code Online (Sandbox Code Playgroud)

一个控件可以设置这样的值:

// Call the GetCurrentCount() method
// to get the current count
int CurrentCount = CounterState.GetCurrentCount();
// Increase the count
CurrentCount++;
// Set Current count on the Session State object
CounterState.SetCurrentCount(CurrentCount);
Run Code Online (Sandbox Code Playgroud)

位于应用程序任何位置的另一个控件可以接收如下值:

   // This method is called when the control is initialized
    protected override void OnInitialized()
    {
        // Subscribe to the StateChanged EventHandler
        CounterState.StateChanged +=
        OnCounterStateAdvancedStateChanged;
    }
    // This method is fired when the CounterState object
    // invokes its StateHasChanged() method
    // This will cause this control to invoke its own
    // StateHasChanged() method refreshing the page
    // and displaying the updated counter value
    void OnCounterStateAdvancedStateChanged(
        object sender, EventArgs e) => StateHasChanged();
    void IDisposable.Dispose()
    {
        // When this control is disposed of
        // unsubscribe from the StateChanged EventHandler
        CounterState.StateChanged -=
        OnCounterStateAdvancedStateChanged;
    }
Run Code Online (Sandbox Code Playgroud)


Mar*_*ott 7

这是一种可能的解决方案,它可能是可行的,因为您可以访问您正在使用的组件的代码。

此解决方案分为三个步骤:

  1. 在您的第一个组件中定义一个事件回调。
  2. 在您的第二个组件中定义一个参数。
  3. 在您的父组件(您的页面)中定义一个属性。

步骤 1:在您的第一个组件中定义一个事件回调。

这将允许您在属性更改时通知父组件(您的页面)。

将 PositionId 属性声明为公共参数。

[Parameter] public int PositionId
Run Code Online (Sandbox Code Playgroud)

你可以让你的 getter 和 setter 保持原样。

将您的输入更改为:

<input type="text" spellcheck="false" @oninput="OnPositionIdChanged" />
Run Code Online (Sandbox Code Playgroud)

像这样声明一个事件回调:

[Parameter] public EventCallback<int> PositionIdChanged { get; set; }
Run Code Online (Sandbox Code Playgroud)

然后定义一个方法来处理这样的变化:

private Task OnPositionIdChanged(ChangeEventArgs e)
{
    PositionId = int.Parse(e.Value.ToString());
    return PositionIdChanged.InvokeAsync(PositionId);
}
Run Code Online (Sandbox Code Playgroud)

现在,当输入中的值发生变化时,将引发一个 EventCallback。

第 2 步:在第二个组件中定义一个参数。

这将允许您将值从您的父组件(您的页面)传递到您的第二个组件。

像这样声明一个公共参数:

[Parameter] public int APositionId {get; set; }
Run Code Online (Sandbox Code Playgroud)

第 3 步:在您的父组件(您的页面)中定义一个属性。

在这里,您定义一个属性,让它在第一个组件中的属性值更改时更新,然后将该值提供给第二个组件中的参数。

在您的页面中定义一个属性,如下所示:

private int SuppliedPosition { get; set; }
Run Code Online (Sandbox Code Playgroud)

将它连接到第一个组件中的更改通知程序,如下所示:

<Position_Hex_IdPair @bind-PositionId="SuppliedPosition"  />
Run Code Online (Sandbox Code Playgroud)

将它提供给第二个组件中的参数,如下所示:

<PositionData APositionId="@SuppliedPosition"/>
Run Code Online (Sandbox Code Playgroud)

我对每个附加属性的命名略有不同,因此希望能明确哪个是哪个。

就是这样!此解决方案的缺点是它需要您更改组件,并向页面添加代码。

Blazor 文档中提供了有关事件回调和参数的更多信息:Blazor 文档

希望这可以帮助。