Cvičení – změna navigace v aplikaci Blazor pomocí direktivy @page

Dokončeno

Blazor má pomocnou rutinu pro stav navigace, která pomáhá kódu jazyka C#spravovat identifikátory URI aplikace. K dispozici je také komponenta NavLink, která nahrazuje prvek.<a> Jednou z funkcí NavLinku je přidání aktivní třídy do odkazů HTML pro nabídky aplikace.

Váš tým začal s aplikací Blazing Pizza a vytvořil komponenty Blazor, které představují pizzy a objednávky. Aplikace teď potřebuje přidat rezervaci a další stránky související s objednávkami.

V tomto cvičení přidáte novou stránku rezervace, přidáte do aplikace horní navigaci a pak použijete komponentu Blazor NavLink ke zlepšení kódu.

Klonování existující aplikace vašeho týmu

Poznámka:

Tento modul používá rozhraní příkazového řádku .NET (CLI) a Visual Studio Code pro místní vývoj. Po dokončení tohoto modulu můžete tyto koncepty použít pomocí sady Visual Studio (Windows) nebo Visual Studio pro Mac (macOS). Pro pokračování vývoje použijte Visual Studio Code pro Windows, Linux a macOS.

Tento modul používá sadu .NET 6.0 SDK. Spuštěním následujícího příkazu v upřednostňovaném terminálu se ujistěte, že máte nainstalovaný .NET 6.0:

dotnet --list-sdks

Zobrazí se výstup podobný následujícímu:

3.1.100 [C:\program files\dotnet\sdk]
5.0.100 [C:\program files\dotnet\sdk]
6.0.100 [C:\program files\dotnet\sdk]

Ujistěte se, že je uvedená verze, na 6 které začíná. Pokud žádný není uvedený nebo příkaz nebyl nalezen, nainstalujte nejnovější sadu .NET 6.0 SDK.

Pokud jste ještě nevytvořili aplikaci Blazor, nainstalujte správnou verzi rozhraní .NET podle pokynů k nastavení blazoru a zkontrolujte, jestli je váš počítač správně nastavený. Zastavte krok Vytvoření aplikace.

  1. Otevřete Visual Studio Code.

  2. Výběrem možnosti Zobrazit otevřete integrovaný terminál v editoru Visual Studio Code. Pak v hlavní nabídce vyberte Terminál.

  3. V terminálu přejděte na místo, kam chcete projekt vytvořit.

  4. Naklonujte aplikaci z GitHubu.

    git clone https://github.com/MicrosoftDocs/mslearn-blazor-navigation.git BlazingPizza
    
  5. Vyberte Soubor a pak vyberte Otevřít složku.

  6. V dialogovém okně Otevřít přejděte do složky BlazingPizza a zvolte Vybrat složku.

    Visual Studio Code vás může vyzvat k nevyřešeným závislostem. Vyberte Obnovit.

  7. Spusťte aplikaci a zkontrolujte, jestli všechno funguje správně.

  8. V editoru Visual Studio Code vyberte F5. Nebo v nabídce Spustit vyberte Spustit ladění.

    Snímek obrazovky znázorňující klonovanou verzi aplikace Blazing Pizza

    Nakonfigurujte některé pizzy a přidejte je do objednávky. Vyberte Pořadí > v dolní části stránky. Zobrazí se výchozí zpráva 404 nenalezena, protože stránka rezervace ještě není.

  9. Pokud chcete aplikaci zastavit, vyberte Shift + F5.

Přidání stránky rezervace

  1. V editoru Visual Studio Code v Průzkumníku souborů vyberte App.razor.

    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" />
        </Found>
        <NotFound>
            <LayoutView>
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
    

    Blok <NotFound> kódu je to, co zákazníci uvidí, jestli se pokusí přejít na stránku, která neexistuje.

  2. V Průzkumníku souborů rozbalte stránky, klikněte pravým tlačítkem na složku a vyberte Nový soubor.

  3. Pojmenujte nový soubor Checkout.razor. V tomto souboru napište následující kód:

    @page "/checkout"
    @inject OrderState OrderState
    @inject HttpClient HttpClient
    @inject NavigationManager NavigationManager
    
    <div class="top-bar">
        <a class="logo" href="">
            <img src="img/logo.svg" />
        </a>
    
        <a href="" class="nav-tab">
            <img src="img/pizza-slice.svg" />
            <div>Get Pizza</div>
        </a>
    
    </div>
    
    <div class="main">
        <div class="checkout-cols">
            <div class="checkout-order-details">
                <h4>Review order</h4>
                @foreach (var pizza in Order.Pizzas)
                {
                    <p>
                        <strong>
                            @(pizza.Size)"
                            @pizza.Special.Name
                            (£@pizza.GetFormattedTotalPrice())
                        </strong>
                    </p>
                }
    
                <p>
                    <strong>
                        Total price:
                        £@Order.GetFormattedTotalPrice()
                    </strong>
                </p>
            </div>
        </div>
    
        <button class="checkout-button btn btn-warning">
            Place order
        </button>
    </div>
    
    @code {
        Order Order => OrderState.Order;
    }
    

    Tato stránka vychází z aktuální aplikace a využívá stav aplikace uložený v OrderStateaplikaci . První div je nová navigace v záhlaví aplikace. Pojďme ho přidat na indexovou stránku.

  4. V průzkumníku souborů rozbalte stránky a pak vyberte index.razor.

  5. <div class="main"> Nad třídu přidejte top-bar html.

    <div class="top-bar">
        <a class="logo" href="">
            <img src="img/logo.svg" />
        </a>
    
        <a href="" class="nav-tab" >
            <img src="img/pizza-slice.svg" />
            <div>Get Pizza</div>
        </a>
    
    </div>
    

    Když jsme na této stránce, bylo by dobré zákazníkům ukázat zvýrazněním odkazu. Tým již vytvořil active třídu css, takže přidejte active do atributu class nav-tab , který již obsahuje styl.

    <div class="top-bar">
        <a class="logo" href="">
            <img src="img/logo.svg" />
        </a>
    
        <a href="" class="nav-tab active" >
            <img src="img/pizza-slice.svg" />
            <div>Get Pizza</div>
        </a>
    
    </div>
    
  6. V editoru Visual Studio Code vyberte F5. Nebo v nabídce Spustit vyberte Spustit ladění.

    Aplikace teď má v horní části pěkný řádek nabídek, který obsahuje logo společnosti. Přidejte pizzu a přejděte na stránku pokladny. V nabídce se zobrazí uvedené pizzy a aktivní indikátor chybí.

    Snímek obrazovky se stránkou pokladny s některými pizzami

  7. Pokud chcete aplikaci zastavit, vyberte Shift + F5.

Povolit zákazníkům vytvořit objednávku

V tuto chvíli stránka pokladny neumožňuje zákazníkům zadávat objednávky. Logika aplikace musí uložit objednávku pro odeslání do kuchyně. Po odeslání objednávky přesměrujme zákazníky zpět na domovskou stránku.

  1. V Průzkumníku souborů rozbalte stránky a vyberte Checkout.razor.

  2. Upravte prvek tlačítka voláním PlaceOrder metody. Přidejte atributy @onclick disabled , jak je znázorněno:

    <button class="checkout-button btn btn-warning" @onclick="PlaceOrder" disabled=@isSubmitting>
      Place order
    </button>
    

    Nechceme, aby zákazníci umisťovali duplicitní objednávky, takže tlačítko Odeslat objednávku zakážeme, dokud se objednávka nezpracuje.

  3. @code Do bloku přidejte tento kód pod Order Order => OrderState.Order; kód.

    bool isSubmitting;
    
    async Task PlaceOrder()
    {
        isSubmitting = true;
        var response = await HttpClient.PostAsJsonAsync(NavigationManager.BaseUri + "orders", OrderState.Order);
        var newOrderId= await response.Content.ReadFromJsonAsync<int>();
        OrderState.ResetOrder();
        NavigationManager.NavigateTo("/");
    }
    

    Předchozí kód zakáže tlačítko Umístit objednávku, publikuje JSON a přidá ho do pizza.db, vymaže objednávku a používá NavigationManager k přesměrování zákazníků na domovskou stránku.

    Ke zpracování objednávky je potřeba přidat kód. Pro tuto úlohu přidejte třídu OrderController. Pokud se podíváte na PizzaStoreContext.cs, zobrazí se pouze podpora databáze entity Framework pro PizzaSpecials. Nejdřív to opravíme.

Přidání podpory entity Framework pro objednávky a pizzy

  1. V Průzkumníku souborů vyberte PizzaStoreContext.cs.

  2. PizzaStoreContext Nahraďte třídu tímto kódem:

      public class PizzaStoreContext : DbContext
      {
            public PizzaStoreContext(
                DbContextOptions options) : base(options)
            {
            }
    
            public DbSet<Order> Orders { get; set; }
    
            public DbSet<Pizza> Pizzas { get; set; }
    
            public DbSet<PizzaSpecial> Specials { get; set; }
    
            public DbSet<Topping> Toppings { get; set; }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
    
                // Configuring a many-to-many special -> topping relationship that is friendly for serialization
                modelBuilder.Entity<PizzaTopping>().HasKey(pst => new { pst.PizzaId, pst.ToppingId });
                modelBuilder.Entity<PizzaTopping>().HasOne<Pizza>().WithMany(ps => ps.Toppings);
                modelBuilder.Entity<PizzaTopping>().HasOne(pst => pst.Topping).WithMany();
            }
    
      }
    

    Tento kód přidá podporu entity frameworku pro třídy objednávek a pizzy aplikace.

  3. V editoru Visual Studio Code v nabídce vyberte Soubor>nový textový soubor.

  4. Vyberte jazyk C# a zadejte tento kód:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    
    namespace BlazingPizza;
    
    [Route("orders")]
    [ApiController]
    public class OrdersController : Controller
    {
        private readonly PizzaStoreContext _db;
    
        public OrdersController(PizzaStoreContext db)
        {
            _db = db;
        }
    
        [HttpGet]
        public async Task<ActionResult<List<OrderWithStatus>>> GetOrders()
        {
            var orders = await _db.Orders
            .Include(o => o.Pizzas).ThenInclude(p => p.Special)
            .Include(o => o.Pizzas).ThenInclude(p => p.Toppings).ThenInclude(t => t.Topping)
            .OrderByDescending(o => o.CreatedTime)
            .ToListAsync();
    
            return orders.Select(o => OrderWithStatus.FromOrder(o)).ToList();
        }
    
        [HttpPost]
        public async Task<ActionResult<int>> PlaceOrder(Order order)
        {
            order.CreatedTime = DateTime.Now;
    
            // Enforce existence of Pizza.SpecialId and Topping.ToppingId
            // in the database - prevent the submitter from making up
            // new specials and toppings
            foreach (var pizza in order.Pizzas)
            {
                pizza.SpecialId = pizza.Special.Id;
                pizza.Special = null;
            }
    
            _db.Orders.Attach(order);
            await _db.SaveChangesAsync();
    
            return order.OrderId;
        }
    }
    

    Předchozí kód umožňuje naší aplikaci získat všechny aktuální objednávky a zadat objednávku. Atribut [Route("orders")] Blazor umožňuje této třídě zpracovávat příchozí požadavky HTTP pro /orders a /orders/{orderId}.

  5. Uložte změny pomocí ctrl+S.

  6. Jako název souboru použijte OrderController.cs. Ujistěte se, že soubor uložíte do stejného adresáře jako OrderState.cs.

  7. V Průzkumníku souborů vyberte OrderState.cs.

  8. V dolní části třídy pod metodou RemoveConfiguredPizza změňte ResetOrder() pořadí:

    public void ResetOrder()
    {
        Order = new Order();
    }
    

Otestování funkčnosti rezervace

  1. V editoru Visual Studio Code vyberte F5. Nebo v nabídce Spustit vyberte Spustit ladění.

    Aplikace by se měla zkompilovat, ale pokud vytvoříte objednávku a pokusíte se ji rezervovat, zobrazí se chyba za běhu. K této chybě dochází, protože databáze SQLLite pizza.db byla vytvořena předtím, než byla podpora objednávek a pizz. Potřebujeme odstranit soubor, aby bylo možné správně vytvořit novou databázi.

  2. Pokud chcete aplikaci zastavit, vyberte Shift + F5.

  3. V Průzkumníku souborů odstraňte pizza.db soubor.

  4. Vyberte F5. Nebo v nabídce Spustit vyberte Spustit ladění.

    Jako test přidejte pizzy, přejděte na pokladnu a umístěte objednávku. Budete přesměrováni na domovskou stránku a uvidíte, že objednávka je teď prázdná.

  5. Pokud chcete aplikaci zastavit, vyberte Shift + F5.

Aplikace se vylepšuje. Máme konfiguraci pizzy a pokladnu. Chceme zákazníkům umožnit, aby po jejich umístění viděli stav objednávky pizzy.

Přidání stránky objednávek

  1. V Průzkumníku souborů rozbalte stránky, klikněte pravým tlačítkem na složku a vyberte Nový soubor.

  2. Pojmenujte nový soubor MyOrders.razor. V tomto souboru napište následující kód:

    @page "/myorders"
    @inject HttpClient HttpClient
    @inject NavigationManager NavigationManager
    
    <div class="top-bar">
        <a class="logo" href="">
            <img src="img/logo.svg" />
        </a>
    
        <a href="" class="nav-tab">
            <img src="img/pizza-slice.svg" />
            <div>Get Pizza</div>
        </a>
    
        <a href="myorders" class="nav-tab active">
            <img src="img/bike.svg" />
            <div>My Orders</div>
        </a>
    </div>
    
    <div class="main">
        @if (ordersWithStatus == null)
        {
            <text>Loading...</text>
        }
        else if (!ordersWithStatus.Any())
        {
            <h2>No orders placed</h2>
            <a class="btn btn-success" href="">Order some pizza</a>
        }
        else
        {
            <div class="list-group orders-list">
                @foreach (var item in ordersWithStatus)
                {
                    <div class="list-group-item">
                        <div class="col">
                            <h5>@item.Order.CreatedTime.ToLongDateString()</h5>
                            Items:
                            <strong>@item.Order.Pizzas.Count()</strong>;
                            Total price:
                            <strong>£@item.Order.GetFormattedTotalPrice()</strong>
                        </div>
                        <div class="col">
                            Status: <strong>@item.StatusText</strong>
                        </div>
                        @if (@item.StatusText != "Delivered")
                        {
                            <div class="col flex-grow-0">
                                <a href="myorders/" class="btn btn-success">
                                    Track &gt;
                                </a>
                            </div>
                        }
                    </div>
                }
            </div>
        }
    </div>
    
    @code {
        List<OrderWithStatus> ordersWithStatus = new List<OrderWithStatus>();
    
        protected override async Task OnParametersSetAsync()
        {
          ordersWithStatus = await HttpClient.GetFromJsonAsync<List<OrderWithStatus>>(
              $"{NavigationManager.BaseUri}orders");
        }
    }
    

    Navigace se musí změnit na všech stránkách, které teď máme, aby obsahovala odkaz na novou stránku Moje objednávky . Otevřete Checkout.razor a Index.razor a nahraďte navigaci tímto kódem:

    <div class="top-bar">
        <a class="logo" href="">
            <img src="img/logo.svg" />
        </a>
    
        <a href="" class="nav-tab active" >
            <img src="img/pizza-slice.svg" />
            <div>Get Pizza</div>
        </a>
    
        <a href="myorders" class="nav-tab" >
            <img src="img/bike.svg" />
            <div>My orders</div>
        </a>
    
    </div>
    

    Pomocí <a> prvků můžeme spravovat, což je aktivní stránka ručně přidáním active třídy css. Pojďme aktualizovat veškerou navigaci tak, aby místo toho používala komponentu NavLink .

  3. Na všech třech stránkách s navigacemi (Index.razor, Checkout.razor a MyOrders.razor) použijte stejný kód Blazor pro navigaci:

    <div class="top-bar">
        <a class="logo" href="">
            <img src="img/logo.svg" />
        </a>
    
        <NavLink href="" class="nav-tab" Match="NavLinkMatch.All">
            <img src="img/pizza-slice.svg" />
            <div>Get Pizza</div>
        </NavLink>
    
        <NavLink href="myorders" class="nav-tab">
            <img src="img/bike.svg" />
            <div>My Orders</div>
        </NavLink>
    </div>
    

    Třída active css je nyní přidána automaticky na stránky pomocí komponenty NavLink . Nemusíte si ho pamatovat na každé stránce, na které je navigace zapnutá.

  4. Posledním krokem je změna NavigationManager přesměrování na myorders stránku po zadání objednávky. V Průzkumníku souborů rozbalte stránky a pak vyberte Checkout.razor.

  5. Změňte metodu PlaceOrder přesměrování na správnou stránku předáním/myorders:NavigationManager.NavigateTo()

    async Task PlaceOrder()
    {
        isSubmitting = true;
        var response = await HttpClient.PostAsJsonAsync($"{NavigationManager.BaseUri}orders", OrderState.Order);
        var newOrderId = await response.Content.ReadFromJsonAsync<int>();
        OrderState.ResetOrder();
        NavigationManager.NavigateTo("/myorders");
    } 
    
  6. V editoru Visual Studio Code vyberte F5. Nebo v nabídce Spustit vyberte Spustit ladění.

    Snímek obrazovky zobrazující stránku objednávky

    Měli byste být schopni objednat si pizzu a pak se podívat na objednávky, které jsou aktuálně v databázi.

  7. Zastavte aplikaci tak, že vyberete Shift + F5.