【问题标题】:Blazor : How to pass ViewModel from Child Component to Parent Component and vice versaBlazor:如何将 ViewModel 从子组件传递到父组件,反之亦然
【发布时间】:2020-06-18 20:46:01
【问题描述】:

如何在 Blazor 中将 ViewModel 从子组件传递到父组件,反之亦然

我正在使用 MVVM 模式构建 Blazor 应用程序。

尝试了以下代码但无法正常工作

[Parameter]
public ViewModel viewModel { get; set; }

【问题讨论】:

    标签: blazor blazor-server-side blazor-client-side


    【解决方案1】:

    我写了一篇关于在 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);
           }
       }
    

    在我的索引页面上,我的注册方法如下所示:

    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 Image Gallery 示例项目的示例,我在用户登录后读取参数:

    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

    也许这会给你一些想法。

    【讨论】:

      猜你喜欢
      • 2019-11-09
      • 2022-11-23
      • 1970-01-01
      • 2021-05-02
      • 2010-12-27
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      相关资源
      最近更新 更多