0

I'm trying to create components made up of smaller components related to data bound from the parent, but I'm not capable of updating the variables in those child components. The idea of doing it this way is to be able to reuse them in other components.

I will show a small example.

When the father component is called OnInitializedAsync add values to the list, that are shown in child 2 component correctly, but if I add a new element to that list in the other child 1 component the list is never updated in view (the data has been update in database)

Father component (base list variable)

<CascadingValue Value="@thelist">
        <Child1></child1>
        <Child2></child2>
<CascadingValue>

@code {
        private List<thetype> thelist { get; set; }

        protected override async Task OnInitializedAsync()
        {
                thelist = service.loadvalues()
        }

}

Child component 1 (add values to list)

Button UpdateList
@code {
        [CascadingParameter]
        public List<thetype> thelist { get; set; }

        private async Task UpdateList()
        {
                thislist changed
        }

}

Child component 2 (show list)

Show list

@code {
        [CascadingParameter]
        public List<thetype> thelist { get; set; }
}

I have tried also using EventCallback, that is the way I use to pass parameters, but this way also is not working is a parameter is shared with multiple cascading components.

        <Child1 thelist="@thelist"></child1>
        <Child2 thelist="@thelist"></child2>

        [Parameter]
        public List<thetype> thelist{ get; set; }

        [Parameter]
        public EventCallback<ChangeEventArgs> thelistChanged { get; set; }

And using StateHasChanged, but the result is the same.

In both ways the updated list can be shown in father component with the new values, but not in the child list component.

I hope you understand what I am trying to ask. All the posts and articles I find are about passing parameters between components, but that's not really my question. I intend that when a component informs the parent of a change, that change is replicated to all descendant components of that parent.

Thanks.

JavierG
  • 1
  • 3
  • I don't understand what you are doing in your last piece of code. The `Parameters` should be defined in Child1.razor and Child2.razor, not in the parent. – T.Trassoudaine Jun 06 '22 at 09:37
  • "In both ways the updated list can be shown in father component with the new values": Are you sure about that? It seems to me that the father component doesn't know about any change, otherwise, all its children depending on the list could know it too. – T.Trassoudaine Jun 06 '22 at 09:39
  • See my answer to this question that shows how to move the data back into the service and use a event driven notification design. https://stackoverflow.com/questions/69558006/how-can-i-trigger-refresh-my-main-razor-page-from-all-of-its-sub-components-wit – MrC aka Shaun Curtis Jun 06 '22 at 09:55

1 Answers1

-1

I have found this solution that works Link solution

Using an Action Parameter that alert to the father component that certain parameter has changed. It is a solution and works, but still I do not understand why my code was not working with EventCallback.

Here I show it applied to my example

Father component (base list variable)

<CascadingValue Value="@thelist">
        <Child1 InvokeChange="@UpdateTheList"></child1>
        <Child2></child2>
<CascadingValue>

@code {
        private List<thetype> thelist { get; set; }

        protected override async Task OnInitializedAsync()
        {
                thelist = service.loadvalues()
        }

        private void UpdateTheList(List<thetype> updatedList)
        {
                thelist = updatedList;
                StateHasChanged();
        }

}

Child component 1 (add values to list)

Button UpdateList
@code {
        [Parameter]
        public Action<List<thetype>> InvokeChange { get; set; }

        [CascadingParameter]
        public List<thetype> thelist { get; set; }

        private async Task UpdateList()
        {
                thislist changed;
                InvokeChange?.Invoke(thelist);
        }

}

Child component 2 (show list)

Show list

@code {
        [CascadingParameter]
        public List<thetype> thelist { get; set; }
}
JavierG
  • 1
  • 3
  • 1
    `Action` is the old way of doing things before they introduced `EventCallBack`. That link you posted is a few years old. If you post your real code I could help you explain why it does not work. – Jesse Good Jun 06 '22 at 20:22
  • Edited applying the link solution to my initial example. I hope this answer can help more people with the same problem despite been marked as "not useful". – JavierG Jun 07 '22 at 18:57