web-dev-qa-db-fra.com

Comment passer des données entre les composants de rasoir sur la même page de blazor?

J'ai cette page blazor

@page "/bearoffdata"
@using BlazorBoinq.Components

<h3>Bearoff Data</h3>

<Position_Hex_IdPair />

<PositionData />

@code {

}

avec ces deux composants de rasoir:

@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;
        }
    }
}

et

@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);
    }
}

Je veux passer le PositionId du premier composant au deuxième composant, je peux donc remplacer le code de code dur 86 dans la dernière ligne, avec le paramètre PositionId. Je reçois une erreur quand j'essaie de poster ceci

On dirait que votre message est principalement du code; S'il vous plaît ajouter quelques détails supplémentaires.

Je ne sais pas vraiment quels détails pour ajouter cela aideraient quelqu'un à répondre à cette question.

4
Hal Heinrich

Oui, vous avez deux contrôles qui ne sont pas directement liés, vous ne pouvez pas simplement passer simplement un paramètre.

Deux options:

Paramètres en cascade: https://docs.microsoft.com/en-us/aspnet/core/blazor/components?view=aspnetcore-30cascade-values-and-paramètres

Ou gestion de l'état. Pour la gestion de l'État, cela peut aider: Mise en œuvre de la gestion des États dans Blazor

Vous avez une classe comme celle-ci:

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);
    }
}

Vous l'enregistrez dans votre fichier startup.cs comme celui-ci:

services.AddScoped<CounterState>();

Vous vous référez à cela dans chaque contrôle .Razor comme celui-ci:

@inject CounterState CounterState

Un contrôle peut définir une valeur comme celle-ci:

// 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);

Un autre contrôle, situé n'importe où dans l'application peut recevoir la valeur comme celle-ci:

   // 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;
    }
2
Michael Washington

Comme alternative, vous pouvez utiliser rx.net.

Vous pouvez utiliser un service comme celui-ci.

public interface IThemeMessageService<T>
{
    void SendMessage(ActionMessage<T> message);

    IObservable<ActionMessage<T>> GetMessage();
}

public class ThemeMessageService<T>: IThemeMessageService<T>
{
    private readonly Subject<ActionMessage<T>> _subject = new Subject<ActionMessage<T>>();

    public void SendMessage(ActionMessage<T> message) => _subject.OnNext(message);

    public IObservable<ActionMessage<T>> GetMessage() => _subject;

}

Envoi du message:

var actionMessage = new ActionMessage<MyData>
{
    Emitter = ThemeMessageEmitter.Component1,
    Data = data
};

ThemeMessageService.SendMessage(actionMessage);

Message de révision:

 ThemeMessageService.GetMessage().Subscribe(p =>
 {

     data= p.Data;

 });

Classe de message:

public class ActionMessage<T>
{
    public ThemeMessageEmitter Emitter { get; set; }
    public T Data { get; set; }
}

EMITRIER: Vous pouvez enregistrer ici le composant envoi des données

public enum ThemeMessageEmitter
{
    Component1 = 1,
    Component2 = 2,
}

N'oubliez pas d'enregistrer le service au démarrage

 services.AddSingleton(typeof(IThemeMessageService<MyData>), typeof(ThemeMessageService<MyData>));

Vous pouvez voir tout en action dans mon thème d'administrateur Blazor https://github.com/amuste/blazoradmindashboard/tree/master/blazoradminindash.client/shared/theme

0
copycat_am