IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

2. diel - Blazor - Rozšírenie Todo aplikácie v .NET Core SPA

V minulej lekcii, Blazor - .NET Core SPA s C # .NET aj na strane klienta , sme si uviedli technológiu Blazor a vytvorili jednoduchú Todo aplikáciu.

V dnešnej lekcii si rozšírime úvodný príklad s Todo aplikáciou o ďalší komponent TodoList. Ukážeme si tiež, ako reagovať na udalosti.

Model úlohy - Todo

Nová komponenta TodoList bude zobrazovať zoznam úloh a ako zdroj údajov teda bude mať kolekciu úloh. Pre úlohu, ktorý v našom prípade obsahuje len text a informáciu o splnení, ešte nemáme vytvorenú modelovú triedu. Poďme to teraz napraviť.

V Solution Exploreri vytvorme novú zložku Model/ a v nej novú triedu s názvom Todo. Do novej triedy pridáme dve vlastnosti:

public class Todo
{
    public string Text { get; set; }
    public bool Done { get; set; }
}

Nový menný priestor Model tiež "zaregistrujte" v súbore _Imports.razor. To nám uľahčí prácu s našou novou triedou vnútri komponentov:

@using BlazorITnetwork.Model

Váš menný priestor, teda časť BlazorITnetwork, sa samozrejme môže vymenovať inak v závislosti na názve projektu.

Komponent TodoList

V priečinku Shared/ vytvorme nový komponent TodoList. Ako som už spomenul vyššie, tento komponent bude zobrazovať zoznam úloh, preto jej pridajme parameter typu IList<Todo>. Zoznam úloh zobrazíme s pomocou cyklu foreach as využitím Bootstrap ho môžeme obaliť trebárs do .card:

<div class="card">
    <div class="card-header">
        <h4 class="card-title">Seznam úkolů</h4>
    </div>
    <div class="card-body">
        @if (Todos.Count == 0)
        {
            <span>Seznam je prázdný ...</span>
        }
        else
        {
            foreach (var todo in Todos)
            {
                <TodoItem Text="@todo.Text" Done="@todo.Done" />
            }
        }
    </div>
</div>
@code {
    [Parameter]
    public IList<Todo> Todos { get; set; } = new List<Todo>();
}

Ak vám Visual Studio neochvejne tvrdí, že triedu Todo nepozná, skúste rebuild aplikácie. Prípadne skontrolujte vyššie popísanú úpravu v súbore _Imports.razor.

V súbore Index.razor teraz zobrazíme nový komponent TodoList. Ako parameter ju odovzdáme zoznam úloh na zobrazenie. Ten by sme v reálnej aplikácii pravdepodobne načítali z databázy, ale my si ho tu jednoducho vytvoríme priamo v kóde:

<TodoList Todos="@todos"/>
@code{
    IList<Todo> todos = new List<Todo>()
    {
        new Todo() {Text = "Naučit se Blazor na ITnetwork"},
        new Todo() {Text = "Vytvořit vlastní Blazor aplikaci"},
        new Todo() {Text = "Pochopit práci s parametry komponenty", Done = true}
    };
}

Ako vyzerá naše aplikácie po spustení je vidieť na nasledujúcom obrázku:

Náhľad aplikácie po spustení - Blazor - C # .NET namiesto JavaScriptu

Pridanie novej úlohy

Rozšírime našu aplikáciu o ďalšiu funkcionalitu. Umožníme užívateľovi pridať novú úlohu. K tomuto účelu vytvoríme komponentu NewItemEntry.razor. HTML časť komponenty sa bude skladať z:

  • popisku,
  • vstupného poľa pre text a
  • tlačidlá pre spustenie akcie.

Pokiaľ bude vstupné pole prázdne, tlačidlo pre pridanie úlohy bude neaktívne. Komponent opäť môžeme naformátovať s pomocou Bootstrap. Časť s kódom bude zatiaľ obsahovať textovú vlastnosť pre nadviazanie na vstupné pole a vlastnosť iba na čítanie, ktorá zneprístupní tlačidlo, ak bude vstupné pole prázdne:

<div class="input-group input-group-lg">
    <div class="input-group-prepend">
        <span class="input-group-text">Nový úkol</span>
    </div>
    <input type="text" class="form-control" @bind="Text"/>
    <div class="input-group-append">
        <button class="btn btn-secondary" disabled=@buttonDisabled>Přidat</button>
    </div>
</div>
@code {
    public string Text { get; set; }

    string buttonDisabled => string.IsNullOrEmpty(Text) ? "disabled" : null;
}

Komponent NewItemEntry si vložíme do komponenty TodoList pod zoznam úloh:

...
<NewItemEntry/>
...

Výsledok vyzerá nejako takto:

Blazor - C # .NET namiesto JavaScriptu

Neaktívne polia

Než pridáme obsluhu stlačení tlačidla, poďme odstrániť na prvý pohľad nezistiteľnú chybu. Naša tlačidlo má byť neaktívne, pretože vstupné pole je prázdne, to je v poriadku. Ovšem ak do vstupného poľa napíšeme nejaký text, tlačidlo zostáva stále neaktívne a to už v poriadku nie je. Použili sme obojsmerný binding, tak kde je problém?

Tlačidlo sa aktivuje až vo chvíli, keď neprázdne pole opustíme (stratí focus), napríklad kliknutím na inú komponent. Dôvodom je, že binding defaultne reaguje na udalosť onchange, ktorá sa vyvolá až pri opustení vstupného poľa. My by sme potrebovali reagovať hneď po stlačení klávesy, takže upravíme udalosť binding na oninput:

...
<input type="text" class="form-control" @bind="Text" @bind:event="oninput"/>
...

Po spustení sa tlačidlo aktivuje hneď po napísaní prvého znaku.

Obsluha kliknutie na tlačidlo

V komponente NewItemEntry nemôžeme pri kliknutí na tlačidlo pridať položku do zoznamu, pretože tento komponent zoznam úloh nemá. Zoznam je v nadradenej komponente TodoList, preto komponenta NewItemEntry iba "oznámi" nadradené komponente, že došlo k stlačeniu tlačidla a poskytne jej text zo vstupného poľa. Výsledné spracovanie tejto "udalosti" teda prebehne v komponente TodoList.

Do komponenty NewItemEntry pridáme parameter OnNewItem typu EventCallback<string> a túto udalosť vyvoláme v novej metóde NewItem(), ktorú zavoláme na stlačenie tlačidla:

...
<button class="btn btn-secondary @buttonDisabled" @onclick="NewItem">Přidat</button>
...
@code {
    ...
    [Parameter]
    public EventCallback<string> OnNewItem { get; set; }

    void NewItem()
    {
       OnNewItem.InvokeAsync(Text);
       Text = string.Empty;
    }
}

Namiesto typu EventCallback<> by sme mohli použiť aj kľúčové slová event a delegate alebo typy Action<>, resp. Func<>. EventCallback je však typ delegáta používaný na vystavenie udalostí naprieč komponentmi. A nadradená komponenta môže samozrejme priradiť obsluhu udalosti EventCallback podriadené komponenty. Pri použití udalosti EventCallback týmto spôsobom sú nadradené a podriadené komponenty automaticky prekreslené pri vyvolaní udalosti. Pri ostatných vyššie spomenutých spôsobov by bolo nutné pre správne prekreslenie volať metódu StateHasChanged().

Do komponenty TodoList pridáme metódu OnNewItem() s parametrom typu string. Túto metódu použijeme pre obslúženie našej novej udalosti na komponente NewItemEntry. Len v nej pridáme nový úlohu s odovzdaným textom do zoznamu úloh:

...
<NewItemEntry OnNewItem="@OnNewItem"/>
...
@code {
    ...
    void OnNewItem(string text)
    {
        Todos.Add(new Todo() { Text = text });
    }
}

Všetko funguje, ako má:-) :

Blazor - C # .NET namiesto JavaScriptu

Reakcia na Enter

Komponent NewItemEntry môžeme upraviť tak, aby okrem stlačení tlačidla vyvolala akciu pridanie úlohy tiež po stlačení klávesy Enter. Pokojne si to skúste najskôr sami;-)

Jedno z možných riešení je nižšie:

...
<input type="text" class="form-control" @bind="Text" @bind:event="oninput" @onkeypress="KeyPress"/>
...
@code {
...
    void KeyPress(KeyboardEventArgs e)
    {
        if (e.Key == "Enter" && !string.IsNullOrEmpty(Text))
            NewItem();
    }
}

To je pre dnešné lekciu všetko. Ak si chcete precvičovať, skúste treba upraviť komponent TodoList tak, aby sa po splnení všetkých úloh sfarbilo záhlaví zelenou farbou.

V ďalšej lekcii, Blazor - Binding , sa pozrieme trochu hlbšie na one-way a two-way binding.


 

Predchádzajúci článok
Blazor - .NET Core SPA s C # .NET aj na strane klienta
Všetky články v sekcii
Blazor - C # .NET namiesto JavaScriptu
Preskočiť článok
(neodporúčame)
Blazor - Binding
Článok pre vás napísal JOF
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity