Лучшая практика для чтения значения дочернего компонента - PullRequest
0 голосов
/ 21 января 2020

Я создал компонент Razor, простой тип ввода, подобный этому:

@using ComponentPackage.Common

<input type="text" @bind="InputValue" />

@code {
    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

    private string inputValue;
    public string InputValue
    {
        get => inputValue;
        set
        {
            inputValue = value;
            ValueChanged.InvokeAsync(value);
        }
    }
}

Затем я настраиваю дочерний компонент следующим образом на странице Razor:

@page "/newpage"
@using ComponentPackage.Common

<ComponentPackage.Components.TextBox ValueChanged="OnValueChanged"></ComponentPackage.Components.TextBox>
<input type="button" @onclick="TestContent" value="Test" />
<br /><br />
You have entered : @ReturnValue

@code {
    [Parameter]
    public string ReturnValue { get; set; }

    private void TestContent()
    {
        // Here I want to get the value from the component
    }

    public void OnValueChanged(string returnValue)
    {
        ReturnValue = returnValue;
    }
}

Из На странице я связываю событие компонента с OnValueChanged. Это работает, как только я покидаю поле, свойство ReturnValue будет обновлено.

Итак, вопрос: как мне прочитать значение в текстовом поле, когда я нажимаю кнопку на странице? Другими словами, я не хочу, чтобы ReturnValue устанавливалось, когда я покидаю текстовое поле. Я пытался использовать bind-InputValue для свойства на странице, но оно всегда равно нулю.

Ответы [ 3 ]

1 голос
/ 22 января 2020

Это мое решение, надеюсь, оно поможет

У меня StateDropdown в качестве дочернего компонента

@inject HttpClient httpClient

@if (States != null)
{
<select id="SearchStateId" name="stateId" @onchange="@StateChange" class="form-control1">
    <option>@InitialText</option>
    @foreach (var state in States)
    {
        <option value="@state.Name">@state.Name</option>
    }
</select>
}

@code {
[Parameter] public string SelectedText { get; set; } = string.Empty;
[Parameter] public string InitialText { get; set; } = "Select State";
[Parameter] public EventCallback<string> SelectedTextChanged { get; set; }
private KeyValue[] States;
protected override async Task OnInitializedAsync()
{
    States = await httpClient.GetJsonAsync<KeyValue[]>("/sample-data/State.json");
}

private async Task StateChange(ChangeEventArgs e)
{
    //Console.WriteLine("It is definitely: " + e.Value.ToString());
    await SelectedTextChanged.InvokeAsync(e.Value.ToString());
}

public class KeyValue
{
    public int Id { get; set; }

    public string Name { get; set; }
}
}

Затем на своей странице я добавил раскрывающийся список состояний с

<StateDropdown @bind-SelectedText="@searchFilter.State" InitialText="All India"></StateDropdown>
<input type="button" id="btnSearch" class="btn-default form-control1" @onclick="@SearchAdertisements" value="Search" />


@code {
 private SearchFilter searchFilter = new SearchFilter();
 public class SearchFilter
{
    public string State { get; set; } = string.Empty;

    public string Category { get; set; } = string.Empty;
}

private async Task SearchAdertisements()
{
    Console.WriteLine(searchFilter.State);
}

Вы можете прочитать для более подробной информации.

0 голосов
/ 22 января 2020

Я попытался изменить это на следующее: .. поэтому он использует bind-InputValue вместо привязки к событию. Но это дает мне следующую ошибку: Объект типа 'ComponentPackage.Components.TextBox' имеет свойство, соответствующее имени 'InputValue', но к нему не применены [ParameterAttribute] или [CascadingParameterAttribute] -

Если вы используете компонент TextBox в родительском компоненте следующим образом:

<TextBox @bind-InputValue="ReturnValue" />

Вы связываете компонент TextBox с переменной, определенной в родительском компоненте, например:

private string ReturnValue {get; set;}

Свойство ReturnValue будет обновлено значениями из TextBox, вызвав EventCallback «делегат».

InputValue (использованный выше: @ bind-InputValue = «ReturnValue») должен быть определен как свойство параметра publi c например:

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

Вам также необходимо определить в дочернем компоненте (с именем TextBox) свойство параметра publi c для EventCallback «делегат», например:

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

Как видите, мы создаем пару из свойства и EventCallback

Если ваше свойство называется InputValue, то ваш E ventCallback должен называться InputValueChanged.

Если ваше свойство называется Value, тогда ваш EventCallback должен называться ValueChanged.

Если ваше свойство называется Text, тогда ваш EventCallback должен называться TextChanged.

Они всегда идут парами.

Теперь go вернитесь к моему первому ответу и изучите код, запустите его, проверьте его, наслаждайтесь и не забудьте проголосовать за мой ответ .. .

0 голосов
/ 22 января 2020

Я думаю, что это то, что вам нужно: Двусторонняя привязка данных в компонентах Следующий код, полный и работающий, это то, что вам нужно ... Скопируйте, вставьте и запустите ...

В следующем примере показано, как выполнить двустороннюю привязку данных между родительским компонентом и его дочерним компонентом. В каждом из этих двух компонентов есть текстовое поле управления. При вводе текста в текстовое поле родительского компонента текст в текстовом поле дочернего компонента изменяется, отражая изменения, сделанные в родительском компоненте, и наоборот ...

ChildComponent.razor

    <div style="border:solid 1px red">
        <h2>Child Component</h2>
        <input type="text" @bind="Text" @bind:event="oninput" />
    </div>

@code {
    private string text { get; set; }

    [Parameter]
    public string Text
    {
        get { return text; }
        set
        {
            if (text != value) {
                text = value;
                if (TextChanged.HasDelegate)
                {
                    TextChanged.InvokeAsync(value);
                }
            }
        }
    }

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

ParentComponent.razor

@page "/ParentComponent"

<h1>Parent Component</h1>

<input type="text" @bind="Text" @bind:event="oninput" />
<p></p>

<ChildComponent @bind-Text="Text" />


@code {
    [Parameter]
    public string Text { get; set; } = "Hello Blazor";
}

Добавьте это содержимое в Shared / NavMenu.razor и проверьте код:

<li class="nav-item px-3">
            <NavLink class="nav-link" href="ParentComponent">
                <span class="oi oi-plus" aria-hidden="true"></span> ParentComponent
            </NavLink>
        </li>

Удачи ... Если что-то не понятно, не стесняйтесь спрашивать ...

...