Я столкнулся с проблемой при попытке использовать повторно используемый компонент ввода для создания нового профиля пользователя. Когда я пытаюсь создать нового пользователя, все данные, введенные в повторно используемый компонент, кажутся пустыми. Я подозреваю, что это связано с проблемой передачи данных от дочернего компонента к родительскому. Интересно, что когда я использую стандартный тег, все работает нормально. Будем очень признательны за любые идеи или предложения о том, как решить эту проблему. Заранее спасибо! Главная страница AddProfile.razor
<form>
<div class = "col-md-6">
<Label LabelClass = "small mb-1" LabelText = "@Loc[nameof(ResourcesEnum.GeneralFirstName)]"/>
<Input InputPlaceholder = "@Loc[nameof(ResourcesEnum.GeneralEnterFirstName)]" BindValue = "@_contact.FirstName" InputClass = "form-control" />
</div>
...
<div class = "btn-wrapper">
<Button BtnClass = "btn btn-primary" IconClass = "bi bi-plus-lg" OnClick = "Submit" />
<Button BtnClass = "btn btn-danger" IconClass = "bi bi-x-circle" OnClick = "() => CancelModalWindow()" DataToggle = "modal" DataTarget = "#exampleModal"/>
</div>
</form>
@code {
private ContactDTO _contact = new ContactDTO();
private List<PartnerDTO>? _partners = new List<PartnerDTO>();
private bool _switchAddPartner = false;
private ModalBootstrap? _modalComponent;
private string? _returnUrl;
private string _submitText = "Save contact";
private string _exam;
protected override async Task OnInitializedAsync()
{
_partners = (await PartnerService.GetAllPartners())?.ToList();
var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("returnUrl", out var url))
{
_returnUrl = url!;
_submitText = "Save and return";
}
}
void HandleInputValueChanged(string value)
{
// Update the input value in the parent component
_contact.FirstName = value;
}
private void HandleInputData(string inputValue)
{
_contact.FirstName = inputValue;
Console.WriteLine($"it is value input: {_contact.FirstName}!!!!!");
}
private void NavigateUrlContactsPage()
{
NavigationManager.NavigateTo("/contacts");
}
private void Cancel()
{
if (!string.IsNullOrEmpty(_returnUrl))
{
NavigationManager.NavigateTo(_returnUrl);
}
else
{
NavigateUrlContactsPage();
}
}
private async Task Submit()
{
Console.WriteLine($"Before Submit: {_contact.FirstName}");
try
{
var createdContact = await ContactService.CreateContactAsync(_contact);
if (!string.IsNullOrEmpty(_returnUrl))
{
Console.WriteLine(createdContact.FirstName);
var returnUrlWithNewContact = $"{_returnUrl}?newContactId = {createdContact.Id}";
NavigationManager.NavigateTo(returnUrlWithNewContact);
}
else
{
Console.WriteLine($"Error{_contact.FirstName}");
NavigateUrlContactsPage();
}
Snackbar.Add($"\u2795 {_contact.FullName}", Severity.Success);
}
catch (Exception ex)
{
Snackbar.Add($"{@Loc[nameof(ResourcesEnum.GeneralError)]}: {ex.Message}", Severity.Error);
}
}
private void CancelModalWindow()
{
_modalComponent.ShowModal($"{@Loc[nameof(ResourcesEnum.GeneralConfirmExit)]}", $"{@Loc[nameof(ResourcesEnum.GeneralConfirmExitQuestion)]}",()=>Cancel() );
}
}
Input.razor (многоразовый компонент)
<input class = "@InputClass" type = "@InputType" placeholder = "@InputPlaceholder" @bind = "@BindValue"/>
@code {
[Parameter] public string InputType { get; set; }
[Parameter] public string InputClass { get; set; }
[Parameter] public string InputPlaceholder { get; set; }
[Parameter] public string BindValue { get; set; }
}





Я воссоздал ваш компонент и надеюсь, что все работает нормально. Ниже мой CInput. Я только изменил привязки, чтобы они работали правильно. В blazor @bind-SomeValue упрощен синтаксис для обработки двух отдельных параметров. Одно — это значение для передачи, а другое — значение, которое нужно получить с помощью EventCallback. Чтобы это работало, оба параметра должны иметь одинаковое имя, но в EventCallback необходимо добавить слово «Изменено» в конце. Когда я использую его, строка передается в обе стороны. Если это не ваша проблема, оставьте отзыв.
<input class = "@ParamInputClass" type = "@ParamInputType" placeholder = "@ParamInputPlaceholder" value = "@ParamBindValue" @onchange = "OnValueChanged" />
@code {
[Parameter] public string ParamInputType { get; set; } = "text";
[Parameter] public string ParamInputClass { get; set; } = string.Empty;
[Parameter] public string ParamInputPlaceholder { get; set; } = string.Empty;
[Parameter] public string ParamBindValue { get; set; } = string.Empty;
[Parameter] public EventCallback<string> ParamBindValueChanged { get; set; }
protected async Task OnValueChanged(ChangeEventArgs? val)
{
if (val is null || val.Value is null) { return; }
string ConvertedToString = ((string) val.Value) ?? string.Empty ;
// Add whatever logic here or even some validation if not using fluent validation on form
await ParamBindValueChanged.InvokeAsync(ConvertedToString);
}
}
А вот компонент, который его использует.
<CInput ParamInputType = "text" ParamInputPlaceholder = "Some Text" ParamInputClass = "fs-3" @bind-ParamBindValue = "@Text" />
<div>
@Text
</div>
@code {
string Text = "Start value";
}
это мне очень помогло и сработало для меня. Можете ли вы объяснить, что происходит в функции OnValueChanged?
onchange — это EventCallback<ChangeEventArgs>, поэтому мне нужно либо иметь тот тип объекта, который привязывается к нему, либо метод с правильной сигнатурой. К сожалению, возвращаемое значение является объектом, поэтому мне нужно выполнить преобразование. Первые строки — это просто проверки для устранения предупреждений. Однако, поскольку вы выбираете тип ввода по значению параметра, это может быть int, datetime или любой другой формат. Поэтому вам необходимо внести изменения в метод OnValueChanged, чтобы проверить, какое значение типа. Я не знаю, чего вы хотите добиться, но, возможно, лучше использовать дженерики в компоненте бритвы.
Найдите в blazor пользовательские входные данные любое количество ресурсов, которые покажут вам, как правильно выполнять привязку. Вы также можете просмотреть стандартный код
InputText, чтобы узнать, как это делается — github.com/dotnet/aspnetcore/blob/main/src/Components/Web/src/…