В выпадающем списке Telerik for Blazor событие не обновляется в сетке. - PullRequest
0 голосов
/ 06 марта 2020

Я использую сетку Telerik, которая показывает строки данных, сгенерированных из базы данных. С каждым элементом базы данных связан временной интервал (по часам). У меня есть TelerikDropDownList, который добавляет параметры фильтрации в сетку (выберите час). Я пытаюсь показать только данные, связанные с часом, выбранным из выпадающего списка в сетке. Я использую WebAssembly, кстати.

Вот компонент сетки:

    <ShowSelect />            

    <TelerikGrid Data="_showItem" Height="80%"
                 Pageable="true" Sortable="true" Groupable="true"
                 FilterMode="Telerik.Blazor.GridFilterMode.FilterMenu"
                 Resizable="true" Reorderable="true" >
        <GridColumns>                
                <GridColumn Field="@(nameof(ShowItem.planned_sequence))" Title="SEQ" />
                <GridColumn Field="@(nameof(ShowItem.matrix_id))" Title="Matrix ID" />
                <GridColumn Field="@(nameof(ShowItem.item_id))" Title="Item ID" />
                <GridColumn Field="@(nameof(ShowItem.item_desc))" Title="Description" />
                <GridColumn Field="@(nameof(ShowItem.item_type_id))" Title="Item Type ID" />
                <GridColumn Field="@(nameof(ShowItem.planned_selling_price))" Title="Planned Price" />
                <GridColumn Field="@(nameof(ShowItem.planned_availabe_qty))" Title="Available Qty" />
                <GridColumn Field="@(nameof(ShowItem.planned_minutes))" Title="P Mins" />
        </GridColumns>
    </TelerikGrid>

@code{
public ShowItem[] _showItem;            

[Inject] HttpClient HttpClient { get; set; }       
[Inject] public AppData ShowData { get; set; }

protected override async Task OnInitializedAsync()
{
    _showItem = await HttpClient.GetJsonAsync<ShowItem[]>("API call...");

    _showItem = _showItem.Where(i => i.time_slot_id == ShowData.SelectedShow).ToArray();
}        
}

Мой компонент ShowSelect:

<TelerikDropDownList Value="ShowData.SelectedShow" Data="@Shows"
                 TextField="ShowName" ValueField="ShowId"
                 ValueChanged="@((int s) => ShowSelected(s))"></TelerikDropDownList>

@code {
public List<Show> Shows { get; set; } = new List<Show>();

public SelectedShow SelectedShow { get; set; } = new SelectedShow();

[Inject] public AppData ShowData { get; set; }

protected override void OnInitialized()
{
    base.OnInitialized();

    var time = DateTime.UtcNow.AddHours(-5); //Fix for no WebAssembly time zone option (Eastern Standard Time)

    for(int i = 15; i > 0; i--)
    {
        var hour = time.AddHours(-i);
        Shows.Add(new Show { ShowId = hour.Hour, ShowName = $"{Convert.ToChar(int.Parse(hour.ToString("HH")) + 65)} - {hour.ToString("hh tt").ToLower()} {hour.ToString("MM/dd/yy")}" }); 
    }

    Shows.Add(new Show { ShowId = time.Hour, ShowName = $"{Convert.ToChar(int.Parse(time.ToString("HH")) + 65)} - {time.ToString("hh tt").ToLower()} {time.ToString("MM/dd/yy")}" });

    for(int i = 1; i < 15; i++)
    {
        var hour = time.AddHours(i);
        Shows.Add(new Show { ShowId = hour.Hour, ShowName = $"{Convert.ToChar(int.Parse(hour.ToString("HH")) + 65)} - {hour.ToString("hh tt").ToLower()} {hour.ToString("MM/dd/yy")}" });
    }
}

public void ShowSelected(int showId)
    {
        ShowData.SelectedShow = showId;

        Show Show = Shows.Where(s => s.ShowId == showId).First();
        SelectedShow.ShowId = Show.ShowId;
        SelectedShow.ShowName = Show.ShowName;
    }
}

Мой сервис AppData:

public class AppData
{
    public int SelectedShow { get; set; } = DateTime.UtcNow.AddHours(-5).Hour;
}

И мои модели:

public class ShowItem
{
    public int network_id { get; set; }
    public DateTime spt_date_id { get; set; }
    public int time_slot_id { get; set; }
    public string show_num { get; set; }
    public int planned_sequence { get; set; }
    public int item_id { get; set; }
    public int matrix_id { get; set; }
    public int item_type_id { get; set; }
    public int planned_selling_price { get; set; }
    public int planned_availabe_qty { get; set; }
    public int planned_minutes { get; set; }
    public string item_desc { get; set; }
}

public class Show
{
    public int ShowId { get; set; }
    public string ShowName { get; set; }
}

public class SelectedShow
{
    public int ShowId { get; set; }
    public string ShowName { get; set; }
}    

У меня проблема в том, что сетка не меняется при выборе другого временного интервала из выпадающего списка. Кто-нибудь знает, где я здесь не так?

1 Ответ

1 голос
/ 27 марта 2020

Я предполагаю, что компонент сетки получает следующее значение, правильно установленное [Inject] public AppData ShowData { get; set; } после раскрывающегося изменения.

Проблема заключается в том, что в компоненте сетки нет обработчика событий или какого-либо кода, который будет обновлять данные сетки.

Событие OnInitializedAsync сработает один раз, когда компонент сетки будет добавлен на страницу в первый раз, и все - он не будет вызываться снова, поэтому ваша служба не будет вызываться снова, чтобы получить новые данные сетки.

Я бы лично обработал это, чтобы выставить событие из компонента ShowSelect, которое я могу использовать в компоненте сетки, чтобы снова вызвать свой сервис .

При этом мне действительно не понадобится AppState, если это все, что в нем содержится.

Я бы также добавил параметр в мой API, чтобы сервер выполнял фильтрацию и отправьте мне обратно только соответствующие данные.

РЕДАКТИРОВАТЬ: Из-за комментариев, я сделал пример выставления события, вот оно (я обрезал некоторые углы в привязке данных, чтобы сделать его короче, b но я надеюсь, что это все еще иллюстрирует точку).

Сначала компонент ShowSelect

<TelerikDropDownList Value="@ShowId" Data="@Shows"
                     ValueChanged="@((int s) => ShowSelected(s))"></TelerikDropDownList>

@code {
    List<int> Shows { get; set; } = new List<int> { 1, 2, 3 };
    [Parameter]
    public int ShowId { get; set; }
    [Parameter]
    public EventCallback<int> OnShowIdChanged { get; set; }

    async Task ShowSelected(int showId)
    {
        ShowId = showId;
        await OnShowIdChanged.InvokeAsync(ShowId);
    }
}

Затем, потребляя это событие в основном компоненте с сеткой:

<ShowSelect ShowId="@ShowId" OnShowIdChanged="@ShowIdChangedHandler" />

<TelerikGrid Data="@MyData" Height="400px" Pageable="true">
    <GridColumns>
        <GridColumn Field="@(nameof(SampleData.Id))" Width="120px" />
        <GridColumn Field="@(nameof(SampleData.Name))" Title="Employee Name" Groupable="false" />
        <GridColumn Field="@(nameof(SampleData.GenerationDate))" Title="Benchmark - data generated at" />
        <GridColumn Field="@(nameof(SampleData.ShowId))" Title="Show ID - see the dropdown" />
    </GridColumns>
</TelerikGrid>

@code {
    public List<SampleData> MyData { get; set; }
    int ShowId { get; set; } // you may not even want this parameter here, but it helps with keeping the dropdown in sync with the main page

    protected override async Task OnInitializedAsync()
    {
        ShowId = 2;//maybe you fetch that from a service too
        MyData = await GetDataFromService(ShowId);
    }

    async Task ShowIdChangedHandler(int showId)
    {
        ShowId = showId;
        MyData = await GetDataFromService(ShowId);
    }

    async Task<List<SampleData>> GetDataFromService(int showId)
    {
        await Task.Delay(500);
        //simulate service here
        var data = Enumerable.Range(1, 30).Select(x => new SampleData
        {
            Id = x,
            Name = "name " + x,
            GenerationDate = DateTime.Now,
            ShowId = showId
        }).ToList();

        return await Task.FromResult(data);
    }

    public class SampleData
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime GenerationDate { get; set; }
        public int ShowId { get; set; }
    }
}
...