web-dev-qa-db-fra.com

Blazor Twoway Binding sur la composante personnalisée

Je crée une application côté serveur blazor et ont des problèmes pour lier une valeur entre deux composants personnalisés.

Je l'ai regardé par exemple différent de la façon dont la liaison ou @bind est censé fonctionner, mais je ne peux pas comprendre ce que l'information à jour sur cette question est.

Étant donné une classe de modèle utilisateur:

public class User
    {
        [Mapping(ColumnName = "short_id")]
        public string ShortId { get; set; }

        public User()
        {

        }
    }

Je veux construire une forme qui affiche toutes les propriétés de cet utilisateur et les a dans une entrée de sorte qu'il peut être modifié et à la fin enregistrée dans une base de données.

Ressemble à mon formulaire (composant parent) ceci:

<div class="edit-user-form">
    <AnimatedUserInput TbText="@User.ShortId" Placeholder="MHTEE Id"/>
    <button class="btn btn-secondary" @onclick="Hide" style="{display:inline-block;}">Back</button>
    <button class="btn btn-primary" @onclick="SaveUser" style="{display:inline-block;}">Save</button>
</div>
@code {
    [Parameter] public vUser User { get; set; }

    [Parameter] public Action Hide { get; set; }

    bool _error = false;

    void SaveUser()
    {
        ValidateUserData();
    }

    void ValidateUserData()
    {
        _error = string.IsNullOrWhiteSpace(User.ShortId);
    }
}

Où est un composant personnalisé AnimatedUserInput qui ressemble à ceci:

<div class="edit-area @FocusClass @WiggleClass">
    <input type="text" @bind="@TbText" />
    <span data-placeholder="@Placeholder"></span>
</div>
@code {
    [Parameter]
    public string TbText { get; set; }

    [Parameter]
    public string Placeholder { get; set; }
}

Maintenant, dans la zone de texte d'entrée, je vois correctement l'objet ShortId du User dans mon composant parent.

Toutefois, si je change le texte dans l'entrée et cliquez sur le Save bouton qui déclenche la ValidateUserData méthode et me permet de regarder le courant User objet que je vois qu'aucun changement ont été fait dans la propriété réelle User.ShortId mais seulement sur l'entrée.

Est-il possible de lier de façon que les changements dans l'entrée seront automatiquement appliqués à la propriété binded?

J'ai plusieurs de ces properies qui doivent être présentées sous la forme qui est la raison pour laquelle je ne veux pas accrocher une coutume OnChanged l'événement pour chacune de ces propriétés.

8
Drew Fyre

Ok donc pour quelqu'un qui trébuche sur ça. J'ai essayé un peu plus et j'ai trouvé une solution. Donc, à mon composant d'entrée personnalisé AnimatedUserInput J'ai ajouté un éventuelCallback que j'appelle chaque fois que la valeur de l'entrée est mise à jour:

@code {

    [Parameter]
    public string TbText
    {
        get => _tbText;
        set
        {
            if (_tbText == value) return;

            _tbText = value;
            TbTextChanged.InvokeAsync(value);
        }
    }

    [Parameter]
    public EventCallback<string> TbTextChanged { get; set; }

    [Parameter]
    public string Placeholder { get; set; }

    private string _tbText;
}

Et la liaison sur mon composant parent ressemble à ceci:

<div class="edit-user-form">
    <AnimatedUserInput @bind-TbText="@User.ShortId" Placeholder="MHTEE Id"/>
    <AnimatedUserInput @bind-TbText="@User.FirstName" Placeholder="First name" />
    <AnimatedUserInput @bind-TbText="@User.LastName" Placeholder="Last name" />
    <AnimatedUserInput @bind-TbText="@User.UserName" Placeholder="Username" />
    <AnimatedUserInput @bind-TbText="@User.StaffType" Placeholder="Staff type" />
    <AnimatedUserInput @bind-TbText="@User.Token" Placeholder="Token" />
    <button class="btn btn-secondary" @onclick="Hide" style="{display:inline-block;}">Back</button>
    <button class="btn btn-primary" @onclick="SaveUser" style="{display:inline-block;}">Save</button>
</div>

@code {
    [Parameter] public vUser User { get; set; }
}

De cette façon, la blazor peut correctement liaison les valeurs ensemble et les mettre à jour des deux côtés de la façon dont je m'attendrais à ce qu'ils se lient.

3
Drew Fyre