如何在Blazor 中将ViewModel从子组件传递到父组件,反之亦然
我正在使用MVVM模式来构建Blazor应用程序。
尝试低于代码但不工作
[Parameter]
public ViewModel viewModel { get; set; }
我在Blazor写了一篇关于亲子交流的博客文章。
https://datajugglerblazor.blogspot.com/2020/01/how-to-use-interfaces-to-communicate.html
我有一个Nuget包,我创建了一个简单的包:
DataJuggler.Blazor.Components
我创建父子通信的方式是通过您的父组件或页面实现这个IBlazorComponentParent接口:
#region using statements
using System.Collections.Generic;
#endregion
namespace DataJuggler.Blazor.Components.Interfaces
{
#region interface IBlazorComponentParent
/// <summary>
/// This interface is used to host IBlazorComponent objects
/// </summary>
public interface IBlazorComponentParent
{
#region Methods
#region FindChildByName(string name)
/// <summary>
/// This method is used to find a child component that has registered with the parent.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
IBlazorComponent FindChildByName(string name);
#endregion
#region ReceiveData(Message message)
/// <summary>
/// This method is used to send data from a child component to the parent component or page.
/// </summary>
/// <param name="data"></param>
void ReceiveData(Message message);
#endregion
#region Refresh()
/// <summary>
/// This method will call StateHasChanged to refresh the UI
/// </summary>
void Refresh();
#endregion
#region Register(IBlazorComponent component)
/// <summary>
/// This method is called by the Sprite to a subscriber so it can register with the subscriber, and
/// receiver events after that.
/// </summary>
void Register(IBlazorComponent component);
#endregion
#endregion
#region Properties
#region Children
/// <summary>
/// This property gets or sets the value for Children.
/// </summary>
public List<IBlazorComponent> Children { get; set; }
#endregion
#endregion
}
#endregion
}
然后您的子组件实现IBlazorComponent
#region using statements
using System.Collections.Generic;
#endregion
namespace DataJuggler.Blazor.Components.Interfaces
{
#region interface IBlazorComponent
/// <summary>
/// This interface allows communication between a blazor componetn and a parent component or page.
/// </summary>
public interface IBlazorComponent
{
#region Methods
#region ReceiveData(Message message)
/// <summary>
/// This method is used to send data from a child component to the parent component or page.
/// </summary>
/// <param name="data"></param>
void ReceiveData(Message message);
#endregion
#endregion
#region Properties
#region Name
/// <summary>
/// This property gets or sets the Name.
/// </summary>
public string Name { get; set; }
#endregion
#region Parent
/// <summary>
/// This property gets or sets the Parent componet or page for this object.
/// </summary>
public IBlazorComponentParent Parent { get; set; }
#endregion
#endregion
}
#endregion
}
然后,当你实现你的组件时,你设置Parent=this:
<div class="galleryimages">
@if (SelectedArtist.HasImages)
{
@foreach (Image image in SelectedArtist.Images)
{
<ImageButton Image=image Parent=this></ImageButton>
}
}
</div>
在我的Image组件上的Parent的setter属性中,我向父级注册:
private IBlazorComponentParent parent;
[Parameter]
public IBlazorComponentParent Parent
{
get { return parent; }
set
{
// store the parent
parent = value;
// if the value for HasParent is true
if (HasParent)
{
// Register with the parent
Parent.Register(this);
}
}
在我的Index页面上,我的Register方法如下所示:
public void Register(IBlazorComponent component)
{
// If the component object exists
if (NullHelper.Exists(component, Children))
{
// If this is the Login component
if (component.Name == "Login")
{
// Set the Signup control
this.Login = component as Login;
}
// add this child
Children.Add(component);
}
}
现在,Parent和Child都有一个ReceiveData方法,您可以在其中发送我所说的MessageObject。
// Create a message
Message message = new Message();
// Send a clear message
message.Text = "";
// Send data
NamedParameter parameter = new NamedParameter();
// set the properties and add new parameter
parameter.Name = "MyData";
parameter.Value = myData;
message.Parameters.Add(parameter);
}
在接收数据的方法中,读取参数并进行更新。
以下是我的Blazor图像库示例项目的一个示例,在该项目中,我在用户登录后读取参数:
public void ReceiveData(Message message)
{
// If the message object exists
if (NullHelper.Exists(message))
{
// if a NewArtist signed up or Logged In
if (message.Text == "Artist Logged In"
{
// if the parameters collection exists
if (message.HasParameters)
{
// iterate the parameters
foreach (NamedParameter parameter in message.Parameters)
{
// if this is the name
if (parameter.Name == "Artist")
{
// Get the login response
LoginResponse loginResponse = parameter.Value as LoginResponse;
// If the loginResponse object exists
if (NullHelper.Exists(loginResponse))
{
// Update the UI that we have a login
LoginComplete(loginResponse);
}
}
}
}
}
else
{
// Set the message text
this.Message = message.Text;
// Update the UI
Refresh();
}
}
}
如果你想查看,这里有一个完整的工作项目:https://github.com/DataJuggler/BlazorImageGallery
如果你无聊的话,这里有一段视频:
https://youtu.be/3xKXJQ4qThQ
也许这会给你一些想法。