Blazor组件:从子组件更新模型时刷新父组件

时间:2019-04-20 15:39:29

标签: c# asp.net-core blazor blazor-server-side

我在ASP.NET Core 3预览版4中使用服务器端Blazor组件。

我有一个父组件和子组件,它们使用相同的共享模型,如下所示:

型号:

public class CountModel
{
    public int Count { get; set; }

    public void Increment()
    {
        Count++;
    }
}

父组件:

@page "/count"

<CascadingValue Value="currentCount">
    <h1>Count parent</h1>

    <p>Current count is : @currentCount.Count</p>

    <button class="btn btn-primary" onclick="@currentCount.Increment">+1 from parent</button>

    <CountChild></CountChild>
</CascadingValue>

@functions {
    private CountModel currentCount = new CountModel();
}

子组件:

<h1>Count child</h1>

<p>Current count is : @currentCount.Count</p>

<button class="btn btn-primary" onclick="@currentCount.Increment">+1 from child</button>


@functions {
    [CascadingParameter]
    private CountModel currentCount { get; set; }
}

这是用于父代和子代的模型的同一实例。 从父级更新模型时,两者均显示正确的增量值。 从子级更新时,只有子级显示正确的值。

从子级更新父组件时,如何强制刷新它?

注意,这里我有一个更新模型的功能,但是当数据绑定到输入时,我希望该解决方案能起作用。

4 个答案:

答案 0 :(得分:4)

通过调用 StateHasChanged 方法更新父状态

创建一个方法来更新父级的状态:

public void RefreshState(){
     this.StateHasChanged();
}

通过级联值或参数将父级传递给子级 示例:

<CascadingValue Value="this">
  <ChildComponent /> 
</CascadingValue>

现在在子组件上声明级联参数:

[CascadingParameter]
public ParentPageType _Parent { get; set; }

现在当你想刷新父级时,只需调用:

_Parent.RefreshState();

答案 1 :(得分:1)

从模型的子组件更新模型时,以下代码片段是刷新父组件的最合适方法。但这增加了更多的讨价还价:父子之间没有依赖性。它不是专门为通知状态更改而创建的。它会通知属性,任何属性何时更改,并可以向订阅者提供其值已更改的属性的名称,新值等。

 using System.ComponentModel;
 using System.Runtime.CompilerServices;
 using System.ComponentModel.DataAnnotations;

这里要注意的重点是我们的模型类实现了INotifyPropertyChanged接口...

CountModel.cs

public class CountModel : INotifyPropertyChanged
{
    private int count;
    public int Count
    {
        get => count;
        set => SetProperty(ref count, value);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new 
                                   PropertyChangedEventArgs(propertyName));
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string 
                                                     propertyName = null)
    {
        if (Equals(storage, value))
        {
            return false;
        }

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    public void Increment()
    {
        Count++;
    }
}

Count.razor

@page "/count"
@implements IDisposable

<CascadingValue Value="currentCount">
    <h1>Count parent</h1>

    <p>Current count is : @currentCount.Count</p>

    <button class="btn btn-primary" @onclick="@currentCount.Increment">+1 
                                                     from parent</button>

    <CountChild></CountChild>
</CascadingValue>

@code {
    private CountModel currentCount = new CountModel();

    protected override void OnInitialized()
    {
       currentCount.PropertyChanged += (sender, args) => StateHasChanged();
    }

    public void Dispose()
    {
        currentCount.PropertyChanged -= (sender, args) => StateHasChanged();
    }
}

CountChild.razor

<h1>Count child</h1>

<p>Current count is : @currentCount.Count</p>

<button class="btn btn-primary" @onclick="@currentCount.Increment">+1 from 
                                                            child</button>


@code {
     [CascadingParameter]
     private CountModel currentCount { get; set; }


}

希望这对您有帮助...

答案 2 :(得分:0)

@glacasa, 级联参数的流向下。为了刷新您的父级,您需要提供一个子组件可以调用的回调,并为其传递一些值。我已经在Blazor的部分中展示了如何在父组件上创建回调,以及如何触发回调,向其传递值...

希望这对您有帮助...

答案 3 :(得分:0)

创建共享服务。在父项中订阅服务的“ RefreshRequested”事件,并从子项中订阅Invoke()。在父方法中调用StateHasChanged();

public interface IMyService
{
 event Action RefreshRequested;
 void CallRequestRefresh;
 }

public class MyService: IMyService
{
    public event Action RefreshRequested;
    public void CallRequestRefresh()
    {
         RefreshRequested?.Invoke();
    }
}


//child component
MyService.CallRequestRefresh();


//parent component
MyService.RefreshRequested += RefreshMe;

private void RefreshMe()
{
    StateHasChanged();
}