Компоненты для шаблонов Blazor - PullRequest
0 голосов
/ 21 апреля 2020

Просто подумайте о том, чтобы придумать шаблонный компонент блейзора для создания одностраничного приложения в стиле CRUD, в которое может быть передан конкретный c объект, поэтому мне не придется писать один и тот же шаблонный код снова и снова.

так, например, как показано ниже, его части могут быть шаблонизированы с помощью объектов RenderFragment:

@typeparam TItem

<div>
    @if (AddObjectTemplate != null)
    {
        @AddObjectTemplate
    }
    else
    {
        <div style="float:left">
            <button class="btn btn-primary" @onclick="AddObject">Add Object</button>
        </div>
    }
</div>

@code {
    [Parameter]
    public RenderFragment AddObjectTemplate { get; set; }

    [Parameter]
    public IList<TItem> Items { get; set; }

}

Однако в дальнейшем мне может понадобиться что-то вроде этого:

<button class="btn btn-default" @onclick="@(() => EditObject(item.Id))">Edit</button>

protected void EditObject(int id)
{
    TItem cust = _itemServices.Details(id);
}

Проблема заключается в том, что приведенный выше вызов EditObject (item.Id) не может разрешить указанный объект c в данный момент, поскольку он не знает, что такое TItem. Есть ли способ использовать указанный c интерфейс в компоненте шаблона, который должен реализовывать каждый объект, или есть другой способ сделать это?

Идея состоит в том, чтобы иметь AddObject, EditObject, DeleteObject et c которые в основном делают одно и то же, но с разными типами объектов.

1 Ответ

0 голосов
/ 21 апреля 2020

Поскольку у вас есть IList<TItem> в качестве параметра, список существует на другом уровне структуры компонента вне этого компонента. Из-за этого вам может быть лучше использовать свойства EventCallBack<T> для методов Add, Edit и Delete, а также устанавливать фактические методы при подключении компонента. Это делает ваш шаблонный компонент только объектом рендеринга, и вы делаете настоящую «работу» близкой к фактическому списку, который требует работы.

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

Templator.razor

@typeparam TItem

<h3>Templator</h3>

@foreach (var item in Items)
{

    @ItemTemplate(item)

    <button @onclick="@(() => EditItemCallBack.InvokeAsync(item))">Edit Item</button>
}

@code {

    [Parameter]
    public IList<TItem> Items { get; set; }

    [Parameter]
    public EventCallback<TItem> EditItemCallBack { get; set; }

    [Parameter]
    public RenderFragment<TItem> ItemTemplate
}

Container.Razor

<h3>Container</h3>

<Templator TItem="Customer" Items="Customers" EditItemCallBack="@EditCustomer">

    <ItemTemplate Context="Cust">
        <div>@Cust.Name</div>
    </ItemTemplate>

</Templator>

@code {

    public List<Customer> Customers { get; set; }

    void EditCustomer(Customer customer)
    {
        var customerId = customer.Id;

        //Do something here to update the customer

    }

}

Customer.cs

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

    public string Name { get; set; }

}

Ключевые моменты здесь будут следующими:

  1. Фактический список root находится вне шаблонного компонента, как и методы для работы в этом списке, так что все вышеперечисленное находится на том же уровне абстракции и той же части кода.

  2. Компонент шаблона получает список, тип для указания типа элементов списка и обратный вызов метода для выполнения для каждого элемента. (или ряд методов, вы можете добавить методы «Добавить» и «Удалить» по своему усмотрению, используя тот же подход). Он также получает фрагмент рендеринга <ItemTemplate>, указанный вами при вызове кода в файле Container.razor.

  3. «foreach» в шаблонном элементе обеспечивает настройку каждого TItem для своего собственного RenderFragment, набора кнопок и функций обратного вызова.

  4. Использование EventCallBack<TItem> в качестве параметра означает, что вы назначаете ему метод, который ожидает обратно весь объект TItem. Это хорошо, так как шаблону сейчас не важно, какой тип TItem, только тот, у которого есть возможность вызывать метод, который принимает TItem в качестве аргумента! Обрабатывается экземпляр того, чем является TItem. теперь ответственность за вызывающий код, и вам не нужно пытаться ограничивать обобщенный тип TItem c. (Что мне еще не повезло, делать в Blazor, возможно, будущие выпуски)

Что касается того, как визуализировать любой TItem, который вы вводите в него, это хорошо объяснено в документации ЗДЕСЬ .

Надеюсь, это поможет!

...