Blazor: Как передать ViewModel из дочернего компонента в родительский компонент и наоборот - PullRequest
0 голосов
/ 06 марта 2020

Как передать ViewModel из дочернего компонента в родительский компонент и наоборот в Blazor

Я использую шаблон MVVM для создания приложения Blazor.

Пробный код ниже, но не работает

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

1 Ответ

0 голосов
/ 06 марта 2020

Я написал сообщение в блоге об общении с родительским ребенком в 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>

В свойстве setter для Parent моего компонента Image я регистрируюсь с родителем:

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, куда вы можете отправлять то, что я вызывал a 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

Возможно, это даст вам некоторые идеи.

...