Search code examples
c#asp.net-corecomponentsblazor-webassembly

How we can call a method from child with State container Blazor Webassembly


I want to call a method from a child Component and I have this code

AppState:

public class AppState
{
    public string MyMessage { get; private set; }
    public string MyMsgToChildren { get; private set; }


    public event Action OnChange;

    public void SetMessage(string msg)
    {
        MyMessage = msg;
        NotifyStateChanged();
    }

    public void SetMessageToChildren(string msg)
    {
        MyMsgToChildren = msg;
        NotifyStateChanged();
    }
    private void NotifyStateChanged() => OnChange?.Invoke();
}

and Child Component #1:

    @inject AppState AppState
<p>============================</p>
<h3>#1 Child</h3>
<p>send from Father :<b>@AppState?.MyMsgToChildren</b>  </p>

<div class="col-sm-6">
    <button @onclick="SetMessage">Send To Parent</button>

</div>
<p>============================</p>

@code {

    protected override void OnInitialized()
    {
        AppState.OnChange += StateHasChanged;
    }
    public void Dispose()
    {
        AppState.OnChange -= StateHasChanged;
    }
    void SetMessage()
    {
        AppState.SetMessage("Message From Child #1");
    }

}

and the #2 Child is the same code with #1 and I have a parent component :

@page "/State"

@inject AppState AppState
<p>============================</p>
<h3>Parent</h3>
<p>send from child:<b>@AppState?.MyMessage</b>  </p>
<div class="col-sm-6">
    <button @onclick="SendMsgTochildren">Send To Parent</button>
</div>
<ChildComponent></ChildComponent>
<Child2Component></Child2Component>

@code {

    public string MsgToChildren { get; private set; } = "Hi, Im your father - ";
    int i = 0;

    protected override void OnInitialized()
    {
        AppState.OnChange += StateHasChanged;
    }
    public void Dispose()
    {
        AppState.OnChange -= StateHasChanged;
    }

    void SendMsgTochildren()
    {
        i++;
        AppState.SetMessageToChildren(MsgToChildren + i.ToString());
    }

    /* I want to call this method from Child*/
    void TargetMethod(int page) 
    { 
    
    }
}

this app works well and just I want to call this method: "TargetMethod(int page)" from one of my child components and I need to pass an integer parameter as well

I want to use this code for pagination. I try to make a component(pagination) and add it to each table component and the pagination will be the grandchild of the main component and I know I can use the other ways but I prefer to use state Container to communicate between pagination and others


Solution

  • I want to call this method: "TargetMethod(int page)" from one of my child components and I need to pass an integer parameter as well

    then you can try like this:

    AppState.cs

     public class AppState
        {
            public Action<int> OnCounterChanged { get; set; }   
        }
    

    Grandparent.razor

        @inject AppState AppState;
    @page "/grandparent"
    <h1>Counter Value from Grandparent : @Counter</h1>
        <Parent/>
    
    
    @code{
    
        public int Counter { get; set; }
    
        protected override void OnInitialized()
        {
            AppState.OnCounterChanged += OnCounterChanged;
        }
    
        private void OnCounterChanged(int counter)
        {
            Counter = counter;
            StateHasChanged();
        }
    }
    

    Parent.razor

    @inject AppState AppState;
    <h1>Counter Value from Parent : @Counter</h1>
    <Child />
    
    
    @code{
    
        public int Counter { get; set; }
    
        protected override void OnInitialized()
        {
            AppState.OnCounterChanged += OnCounterChanged;
        }
    
        private void OnCounterChanged(int counter)
        {
            Counter = counter;
            StateHasChanged();
        }
    }
    <Child />
    

    Child.razor

    @inject AppState AppState;
    <h1>Counter Value from child : @Counter</h1>
    <button class="btn btn-primary" @onclick="UpdateCounter"> Update Counter</button>
    @code{
    
        public int Counter { get; set; }
    
        private void UpdateCounter()
        {
            AppState.OnCounterChanged.Invoke(++Counter);
        }
    }
    

    I'm updating the counter from the child component and invoking the event with an int parameter. (it's just a demo)