gla*_*asa 20 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++;
}
}
Run Code Online (Sandbox Code Playgroud)
父组件:
@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();
}
Run Code Online (Sandbox Code Playgroud)
子组件:
<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; }
}
Run Code Online (Sandbox Code Playgroud)
它是用于父级和子级的模型的相同实例。当模型从父模型更新时,两者都显示正确的增量值。当它从孩子更新时,只有孩子显示正确的值。
从子组件更新时,如何强制刷新父组件?
请注意,这里我有一个更新模型的函数,但我希望该解决方案在数据绑定到输入时起作用。
Lau*_*e73 34
创建共享服务。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();
}
Run Code Online (Sandbox Code Playgroud)
级联参数的流动是向下的。为了刷新您的父组件,您希望提供一个子组件可以调用的回调,并向其传递一些值。我已经在 Blazor 部分展示了如何在父组件上创建回调,以及如何触发回调,向它传递一个值。
以下代码片段是在从其子组件更新模型时刷新父组件的最合适方法。但它增加了更多的讨价还价:父母和孩子之间没有依赖。它不是专门为通知状态更改而创建的。它通知属性、任何属性何时发生更改,并且可以向订阅者提供其值已更改的属性的名称、新值等。
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.ComponentModel.DataAnnotations;
Run Code Online (Sandbox Code Playgroud)
这里要注意的要点是我们的模型类实现了 INotifyPropertyChanged 接口......
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++;
}
}
Run Code Online (Sandbox Code Playgroud)
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
<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; }
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助...
通过调用它的 StateHasChanged 方法更新父状态
创建一个方法来更新父级的状态:
public void RefreshState(){
this.StateHasChanged();
}
Run Code Online (Sandbox Code Playgroud)
通过级联值或参数将父级传递给子级示例:
<CascadingValue Value="this">
<ChildComponent />
</CascadingValue>
Run Code Online (Sandbox Code Playgroud)
现在在 Child 的组件上声明级联参数:
[CascadingParameter]
public ParentPageType _Parent { get; set; }
Run Code Online (Sandbox Code Playgroud)
现在当你想刷新父级时,只需调用:
_Parent.RefreshState();
Run Code Online (Sandbox Code Playgroud)
如果子组件调用父组件提供的 EventCallback,则父组件将重新呈现。所以从技术上来说,你可以这样做:
[Parameter]
public EventCallback OnIncrement { get; set; }
Run Code Online (Sandbox Code Playgroud)
<button @onClick=@(args => HandleClick()) ... >
Task HandleClick()
{
currentCount.Increment();
return OnIncrement.InvokeAsync();
}
Run Code Online (Sandbox Code Playgroud)
<CountChild OnIncrement=@( () => {} )/>
Run Code Online (Sandbox Code Playgroud)
即使提供的回调不执行任何操作,它的调用也会触发重新渲染。
请注意,具有“不执行任何操作”的方法/函数通常被认为是代码异味。
| 归档时间: |
|
| 查看次数: |
25166 次 |
| 最近记录: |