Skip to content

Latest commit

Β 

History

History
160 lines (105 loc) Β· 7.67 KB

File metadata and controls

160 lines (105 loc) Β· 7.67 KB

μ»΄ν¬λ„ŒνŠΈμ™€ λ ˆμ΄μ•„μ›ƒ

이 μ„Έμ…˜μ—μ„œλŠ” λΈ”λ ˆμ΄μ €λ₯Ό μ΄μš©ν•˜μ—¬ ν”Όμž κ°€κ²Œ 앱을 λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€. 이 앱은 μ‚¬μš©μžκ°€ ν”Όμžλ₯Ό μ£Όλ¬Έν•˜κ³  토핑을 λ³€κ²½ν•  수 있으며 μ£Όλ¬Έ 배달을 좔적할 수 μžˆμŠ΅λ‹ˆλ‹€.

ν”Όμž κ°€κ²Œ μ•±μ˜ 첫 걸음

이 λ ˆν¬μ§€ν† λ¦¬μ— ν”Όμž κ°€κ²Œ 앱을 μœ„ν•œ 초기 μ†”λ£¨μ…˜μ„ μ€€λΉ„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 이제 λ ˆν¬μ§€ν† λ¦¬λ₯Ό λ³΅μ‚¬ν•˜μ„Έμš”. "save-points" 폴더에 각 μ„Έμ…˜λ³„λ‘œ μ€€λΉ„κ°€ λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. starting pointλ₯Ό μ°Ύμ•„λ³΄μ„Έμš”.

Note: 이 μ›Œν¬μƒ΅ μ½”λ“œλ₯Ό μ‹œμŠ€ν…œμ˜ λ‹€λ₯Έ μœ„μΉ˜μ— λ³΅μ‚¬ν•˜λŠ” 경우, λ ˆν¬μ§€ν† λ¦¬ root에 μžˆλŠ” Directory.Build.props νŒŒμΌλ„ ν•¨κ»˜ 볡사해야 ν•©λ‹ˆλ‹€.

이 μ†”λ£¨μ…˜μ€ 4개의 ν”„λ‘œμ νŠΈλ₯Ό 이미 ν¬ν•¨ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. image

  • BlazingPizza.Client: λΈ”λ ˆμ΄μ € ν”„λ‘œμ νŠΈ μž…λ‹ˆλ‹€. μ•± UI μ»΄ν¬λ„ŒνŠΈκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

  • BlazingPizza.Server: λΈ”λ ˆμ΄μ € 앱을 ν˜ΈμŠ€νŒ…ν•˜λŠ” ASP.NET Core ν”„λ‘œμ νŠΈμ΄λ©° 이 μ•±μ˜ λ°±μ—”λ“œ μ„œλΉ„μŠ€μž…λ‹ˆλ‹€.

  • BlazingPizza.Shared: 이 μ•±μ—μ„œ κ³΅μœ ν•˜λŠ” μ½”λ“œκ°€ ν¬ν•¨λœ ν”„λ‘œμ νŠΈμž…λ‹ˆλ‹€.

  • BlazingPizza.ComponentsLibrary: 이후 μ„Έμ…˜μ—μ„œ μ‚¬μš©λ  μ»΄ν¬λ„ŒνŠΈμ™€ ν—¬νΌμ½”λ“œ λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€.

BlazingPizza.Server ν”„λ‘œμ νŠΈκ°€ μ‹œμž‘ ν”„λ‘œμ νŠΈλ‘œ μ„€μ •λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

앱을 μ‹€ν–‰ν•˜λ©΄ ν˜„μž¬λŠ” λ‹¨μˆœν•œ ν™ˆνŽ˜μ΄μ§€κ°€ ν‘œμ‹œλ  κ²ƒμž…λ‹ˆλ‹€.

image

이 ν™ˆ νŽ˜μ΄μ§€μ˜ μ½”λ“œλ₯Ό 보기 μœ„ν•΄ BlazingPizza.Client ν”„λ‘œμ νŠΈμ— μžˆλŠ” Pages/Index.razor νŒŒμΌμ„ μ—΄μ–΄λ³΄μ„Έμš”.

@page "/"

<h1>Blazing Pizzas</h1>

이 ν™ˆνŽ˜μ΄μ§€λŠ” 단일 μ»΄ν¬λ„ŒνŠΈλ‘œ κ΅¬ν˜„λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. @page μ§€μ‹œλ¬Έμ€ Index μ»΄ν¬λ„ŒνŠΈκ°€ νŠΉμ • 경둜의 λΌμš°νŒ… κ°€λŠ₯ν•œ νŽ˜μ΄μ§€μž„μ„ μ§€μ •ν•©λ‹ˆλ‹€.

ν”Όμž 메뉴 λͺ©λ‘ ν‘œμ‹œ

첫 번째둜 ν™ˆνŽ˜μ΄μ§€μ— μ£Όλ¬Έ κ°€λŠ₯ν•œ ν”Όμž 메뉴λ₯Ό ν‘œμ‹œν•˜λŠ” 것뢀터 μ§„ν–‰ν•  κ²ƒμž…λ‹ˆλ‹€. 이 λͺ©λ‘μ€ Index μ»΄ν¬λ„ŒνŠΈ μƒνƒœμ— ν¬ν•¨λ©λ‹ˆλ‹€.

Index.razor νŽ˜μ΄μ§€μ— 메뉴 λͺ©λ‘μ„ μ €μž₯ν•  λͺ©λ‘ ν•„λ“œλ₯Ό μ €μž₯ν•  μ½”λ“œλ₯Ό @code λΈ”λŸ­μœΌλ‘œ μΆ”κ°€ν•΄ μ£Όμ„Έμš”.

@code {
    List<PizzaSpecial> specials;
}

@code λΈ”λŸ­μ•ˆμ˜ μ½”λ“œλŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό μœ„ν•΄ μƒμ„±λœ ν΄λž˜μŠ€μ— μΆ”κ°€λ©λ‹ˆλ‹€. PizzaSpecial νƒ€μž…μ€ BlazingPizza.Shared에 이미 μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

메뉴 λͺ©λ‘μ„ 얻을 λ €λ©΄ λ°±μ—”λ“œμ˜ APIλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•©λ‹ˆλ‹€. λΈ”λ ˆμ΄μ €λŠ” κΈ°λ³Έκ°’μœΌλ‘œ 이미 μ„€μ •λœ HttpClientλ₯Ό μ˜μ‘΄μ„± μ£Όμž…μ„ 톡해 μ œκ³΅ν•©λ‹ˆλ‹€. @inject μ§€μ‹œμ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ Index μ»΄ν¬λ„ŒνŠΈμ— HttpClientλ₯Ό μ£Όμž…ν•©λ‹ˆλ‹€.

@page "/"
@inject HttpClient HttpClient

@inject μ§€μ‹œλ¬Έμ€ 기본적으둜 속성 μœ ν˜•κ³Ό 속성 이름을 μ§€μ •ν•˜λŠ” κ²ƒμœΌλ‘œ μ»΄ν¬λ„ŒνŠΈμ— μƒˆ 속성을 μ •μ˜ν•©λ‹ˆλ‹€. 이 속성은 쒅속성 μ£Όμž…μ„ 톡해 제곡 λ©λ‹ˆλ‹€.

ν”Όμž 메뉴 λͺ©λ‘μ„ λ°›κΈ° μœ„ν•΄ @code λΈ”λŸ­μ— OnInitializedAsync λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•©λ‹ˆλ‹€. 이 λ©”μ„œλ“œλŠ” μ»΄ν¬λ„ŒνŠΈ 생λͺ…μ£ΌκΈ°μ˜ μΌλΆ€λ‘œ μ»΄ν¬λ„ŒνŠΈκ°€ μ΄ˆκΈ°ν™”λ˜κ³  λ‚˜μ„œ ν˜ΈμΆœλ©λ‹ˆλ‹€. μ‘λ‹΅μœΌλ‘œ 온 JSON을 μ—­μ§λ ¬ν™”ν•˜κΈ° μœ„ν•΄ GetFromJsonAsync<T>() λ©”μ„œλ“œλ₯Ό μ΄μš©ν•©λ‹ˆλ‹€.

@code {
    List<PizzaSpecial> specials;

    protected override async Task OnInitializedAsync()
    {
        specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>("specials", BlazingPizza.OrderContext.Default.ListPizzaSpecial);
    }
}

/specials APIλŠ” minimal API둜 μ •μ˜λ˜μ–΄ 있으며 BlazingPizza.Server ν”„λ‘œμ νŠΈμ˜ PizzaApiExtensions.csνŒŒμΌμ—μ„œ ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.

minimal API와 κ΄€λ ¨ν•œ 상세 λ‚΄μš©μ€ ASP.NET Coreλ₯Ό μ‚¬μš©ν•˜μ—¬ μ΅œμ†Œ API λ§Œλ“€κΈ°λ₯Ό μ°Έκ³ ν•˜μ„Έμš”.

Note: BlazingPizza.OrderContext.Default.ListPizzaSpecialλŠ” source generators둜 JSON을 μ§λ ¬ν™”ν•œ κ²ƒμž…λ‹ˆλ‹€.

μ»΄ν¬λ„ŒνŠΈκ°€ μ΄ˆκΈ°ν™”λ˜λ©΄ λ§ˆν¬μ—…μ΄ λ Œλ”λ§λ©λ‹ˆλ‹€. Index μ»΄ν¬λ„ŒνŠΈμ˜ λ§ˆν¬μ—…μ„ μ•„λž˜μ™€ 같이 ν”Όμž 메뉴 λͺ©λ‘μ„ ν‘œμ‹œν•˜λ„λ‘ μˆ˜μ •ν•΄ μ£Όμ„Έμš”.

<div class="main">
    <ul class="pizza-cards">
        @if (specials != null)
        {
            @foreach (var special in specials)
            {
                <li style="background-image: url('@special.ImageUrl')">
                    <div class="pizza-info">
                        <span class="title">@special.Name</span>
                        @special.Description
                        <span class="price">@special.GetFormattedBasePrice()</span>
                    </div>
                </li>
            }
        }
    </ul>
</div>

Ctrl-F5λ₯Ό 눌러 앱을 μ‹€ν–‰ν•΄ μ£Όμ„Έμš”. 이제 μ£Όλ¬Έ κ°€λŠ₯ν•œ 메뉴 λͺ©λ‘μ΄ 보일 κ²ƒμž…λ‹ˆλ‹€.

image

λ ˆμ΄μ•„μ›ƒ λ§Œλ“€κΈ°

λ‹€μŒμœΌλ‘œ μ•±μ˜ λ ˆμ΄μ•„μ›ƒμ„ λ§Œλ“­λ‹ˆλ‹€.

λΈ”λ ˆμ΄μ €μ˜ λ ˆμ΄μ•„μ›ƒ μ—­μ‹œ μ»΄ν¬λ„ŒνŠΈμž…λ‹ˆλ‹€. λ ˆμ΄μ•„μ›ƒμ˜ 본문을 λ Œλ”λ§ν•  수 μžˆλŠ” Bodyλ₯Ό μ •μ˜ν•˜λŠ” LayoutComponentBaseλ‘œλΆ€ν„° μƒμ†λ©λ‹ˆλ‹€. μš°λ¦¬κ°€ μ‚¬μš©ν•  ν”Όμž κ°€κ²Œ μ•±μ˜ λ ˆμ΄μ•„μ›ƒ μ»΄ν¬λ„ŒνŠΈλŠ” Shared/MainLayout.razor νŒŒμΌμ— μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

@inherits LayoutComponentBase

<div class="content">
    @Body
</div>

λ ˆμ΄μ•„μ›ƒμ΄ νŽ˜μ΄μ§€μ™€ μ–΄λ–»κ²Œ μ—°κ΄€λ˜μ–΄ μžˆλŠ”μ§€ 보렀면 App.razor 파일의 <Router> μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚΄νŽ΄λ³΄μ„Έμš”. DefaultLayout 맀개 λ³€μˆ˜λŠ” λ ˆμ΄μ•„μ›ƒμ„ μ§€μ •ν•˜μ§€ μ•Šμ€ νŽ˜μ΄μ§€μ— μ‚¬μš©λ˜λŠ” λ ˆμ΄μ•„μ›ƒμ„ κ²°μ •ν•©λ‹ˆλ‹€.

νŽ˜μ΄μ§€ λ‹¨μœ„λ‘œ DefaultLayoutλ₯Ό μž¬μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄μ„œλŠ” .razor νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈ 맨 μœ„μ— @layout SomeOtherLayout 같은 μ§€μ‹œλ¬Έμ„ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

MainLayout μ»΄ν¬λ„ŒνŠΈλ₯Ό μˆ˜μ •ν•˜μ—¬ ν™ˆνŽ˜μ΄μ§€μ˜ 탐색 링크와 λΈŒλžœλ“œ λ‘œκ³ κ°€ μžˆλŠ” 상단 메뉴λ₯Ό μΆ”κ°€ν•΄ μ£Όμ„Έμš”.

@inherits LayoutComponentBase

<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>
</div>

<div class="content">
    @Body
</div>

λΈ”λ ˆμ΄μ €λŠ” NavLink μ»΄ν¬λ„ŒνŠΈλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. μ»΄ν¬λ„ŒνŠΈλŠ” μ»΄ν¬λ„ŒνŠΈμ˜ νƒ€μž… 이름과 맀개 λ³€μˆ˜λ₯Ό μ†μ„±μœΌλ‘œ μ§€μ •ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

NavLink μ»΄ν¬λ„ŒνŠΈλŠ” ν˜„μž¬ URL이 링크의 μ£Όμ†Œμ™€ μΌμΉ˜ν•  λ•Œ active 클래슀λ₯Ό μΆ”κ°€ν•˜λŠ” 것을 μ œμ™Έν•˜λ©΄ 액컀 νƒœκ·Έμ™€ λ™μΌν•©λ‹ˆλ‹€. NavLinkMatch.All은 전체 URL(URL Prefix만이 μ•„λ‹Œ)이 μΌμΉ˜ν•˜μ˜€μ„ λ•Œλ§Œ 링크가 ν™œμ„±ν™”λ˜μ–΄μ•Ό ν•˜λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. NavLink의 μžμ„Έν•œ λ‚΄μš©μ€ 이후 μ„Έμ…˜μ—μ„œ 더 μžμ„Ένžˆ λ‹€λ£¨κ² μŠ΅λ‹ˆλ‹€.

Ctrl-F5λ₯Ό 눌러 앱을 μ‹€ν–‰ν•΄ μ£Όμ„Έμš”. μƒˆλ‘œμš΄ λ ˆμ΄μ•„μ›ƒμ΄ μ μš©λ˜μ–΄ ν”Όμž κ°€κ²Œ 앱이 μ•„λž˜ 이미지와 같이 보일 κ²ƒμž…λ‹ˆλ‹€.

image

λ‹€μŒ μ„Έμ…˜ - λ‚΄ ν”Όμž λ§Œλ“€κΈ°

원문 읽기 - Components and Layout