μ΄μ νΌμ κ°κ² μ¬μ©μλ μ£Όλ¬Έ μνλ₯Ό μ€μκ°μΌλ‘ μΆμ ν μ μμ΅λλ€. μ΄ μΈμ μμλ μλ°μ€ν¬λ¦½νΈ μνΈμ΄μ©μ±μ μ¬μ©νμ¬ "λ΄ νΌμλ μ΄λ μμ§?!?"λΌλ μ€λλ μ§λ¬Έμ λ΅νλ μ£Όλ¬Έ μν νμ΄μ§μ μ€μκ° μ§λλ₯Ό μΆκ°ν©λλ€.
ComponentsLibrary νλ‘μ νΈμλ λ§μ»€ μΈνΈμ μμΉλ₯Ό νμνκ³ μκ° κ²½κ³Όμ λ°λ₯Έ μμ§μμ μ λλ©μ΄μ
μ μν΄ μ΄λ―Έ μμ±λ Map μ»΄ν¬λνΈκ° ν¬ν¨λμ΄ μμ΅λλ€. μ΄ μ»΄ν¬λνΈλ₯Ό μ¬μ©νμ¬ μ¬μ©μμ νΌμ μ£Όλ¬Έμ΄ λ°°λ¬ λλ μμΉλ₯Ό νμνμ§λ§ Map μ»΄ν¬λνΈκ° μ΄λ»κ² ꡬνλλμ§ μ΄ν΄λ³΄κ² μ΅λλ€.
Map.razor νμΌμ μ΄κ³ μλ μ½λλ₯Ό μ΄ν΄λ³΄μΈμ.
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime
<div id="@elementId" style="height: 100%; width: 100%;"></div>
@code {
string elementId = $"map-{Guid.NewGuid().ToString("D")}";
[Parameter] double Zoom { get; set; }
[Parameter] List<Marker> Markers { get; set; }
protected async override Task OnAfterRenderAsync(bool firstRender)
{
await JSRuntime.InvokeVoidAsync(
"deliveryMap.showOrUpdate",
elementId,
Markers);
}
}Map κ΅¬μ± μμλ μ’
μμ± μ£Όμ
μ μ¬μ©νμ¬ IJSRuntime μΈμ€ν΄μ€λ₯Ό κ°μ Έμ΅λλ€. μ΄ μλΉμ€λ₯Ό μ¬μ©νλ©΄ InvokeVoidAsync λλ InvokeAsync<TResult> λ©μλλ₯Ό νΈμΆνμ¬ λΈλΌμ°μ API λλ κΈ°μ‘΄ JavaScript λΌμ΄λΈλ¬λ¦¬μ λν JavaScript νΈμΆμ μνν μ μμ΅λλ€. μ΄ λ©μλμ 첫 λ²μ§Έ λ§€κ°λ³μλ λ£¨νΈ window κ°μ²΄λ₯Ό κΈ°μ€μΌλ‘ νΈμΆν JavaScript ν¨μμ κ²½λ‘λ₯Ό μ§μ ν©λλ€. λλ¨Έμ§ λ§€κ°λ³μλ JavaScript ν¨μμ μ λ¬ν μΈμμ
λλ€. μΈμλ JavaScriptλ‘ μ²λ¦¬λ μ μλλ‘ JSONμΌλ‘ μ§λ ¬νλ©λλ€.
Map μ»΄ν¬λνΈλ λ¨Όμ μ§λμ κ³ μ IDλ‘ divλ₯Ό λ λλ§ν λ€μ deliveryMap.showOrUpdate ν¨μλ₯Ό νΈμΆνμ¬ μ§μ λ λ§μ»€κ° Map μ»΄ν¬λνΈμ μ λ¬ν΄ μ§λμ νμν©λλ€. μ΄ μμ
μ OnAfterRenderAsync ν¨μμμ μλ£λμ΄ μ»΄ν¬λνΈ μλͺ
μ£ΌκΈ° μ΄λ²€νΈμμ μνμ΄ μλ£λ©λλ€. deliveryMap.showOrUpdate ν¨μλ wwwroot/deliveryMap.js νμΌμ μ μλμ΄ μμΌλ©° leaflet.jsκ³Ό OpenStreetMapμ μ΄μ©νμ¬ μ§λμ νμν©λλ€. μ΄ μ½λμ μλ λ°©μμ λν μΈλΆ μ¬νμ μ€μ λ‘ μ€μνμ§ μμ΅λλ€. μ€μν μ μ λͺ¨λ JavaScript ν¨μλ₯Ό μ΄λ° λ°©μμΌλ‘ νΈμΆν μ μλ€λ κ²μ
λλ€.
μ΄λ° νμΌμ μ΄λ»κ² λΈλ μ΄μ μ±μ μΆκ°νλμ? λΈλ μ΄μ λΌμ΄λΈλ¬λ¦¬ νλ‘μ νΈ(Sdk="Microsoft.NET.Sdk.Razor")λ₯Ό μ¬μ©νλ©΄ wwwroot/ ν΄λμ μλ λͺ¨λ νμΌμ λΌμ΄λΈλ¬λ¦¬μ ν¨κ» λ²λ€λ‘ μ 곡λ©λλ€. μλ² νλ‘μ νΈλ μ μ νμΌ λ―Έλ€μ¨μ΄λ₯Ό μ¬μ©νμ¬ μ΄λ¬ν νμΌμ μλμΌλ‘ μ 곡ν©λλ€.
λΈλ μ΄μ ν΄λΌμ΄μΈνΈ μ±μ νΈμ€ν
νλ νμ΄μ§μ μνλ νμΌ(μ΄ κ²½μ° .js λ° .css)μ ν¬ν¨μν€λ λ§ν¬κ° λ§μ§λ§μ μμ΅λλ€. index.htmlμλ _content/BlazingPizza.ComponentsLibrary/localStorage.jsμ κ°μ μλ URIλ₯Ό μ¬μ©νμ¬ μ΄λ¬ν νμΌμ΄ ν¬ν¨λ©λλ€. μ΄λ λΈλ μ΄μ ν΄λμ€ λΌμ΄λΈλ¬λ¦¬(_content/<λΌμ΄λΈλ¬λ¦¬ μ΄λ¦>/<νμΌ κ²½λ‘>)μ ν¨κ» λ²λ€λ‘ μ 곡λλ μ°Έμ‘° νμΌμ μΌλ°μ μΈ ν¨ν΄μ
λλ€.
Mapμ μ
λ ₯μ μμνλ©΄ νΈμ§κΈ°μμ μμ± κΈ°λ₯μ μ 곡νμ§ μλλ€λ κ²μ μ μ μμ΅λλ€. μ΄λ μμμ μ»΄ν¬λνΈ κ°μ λ°μΈλ©μ΄ C#μ λ€μμ€νμ΄μ€ λ°μΈλ© κ·μΉμ μν΄ μ μ΄λκΈ° λλ¬Έμ
λλ€. Map κ΅¬μ± μμλ BlazingPizza.ComponentsLibrary.Map λ€μμ€νμ΄μ€μ μ μλμ΄ μμ§λ§ μ΄μ λν @usingμ΄ μμ΅λλ€.
μ΄ λ€μμ€νμ΄μ€μ λν @usingμ λ£¨νΈ _Imports.razorμ μΆκ°νμ¬ μ΄ μ»΄ν¬λνΈ λ²μλ‘ κ°μ Έμ΅λλ€.
@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.JSInterop
@using BlazingPizza.Client
@using BlazingPizza.Client.Shared
@using BlazingPizza.ComponentsLibrary
@using BlazingPizza.ComponentsLibrary.Maptrack-order-details div λ°λ‘ μλμ λ€μμ μΆκ°νμ¬ OrderDetails νμ΄μ§μ Map κ΅¬μ± μμλ₯Ό μΆκ°ν©λλ€.
<div class="track-order-map">
<Map Zoom="13" Markers="orderWithStatus.MapMarkers" />
</div>μ΄μ μλ μ»΄ν¬λνΈμ @usingμ μΆκ°ν νμκ° μμλ μ΄μ λ λ£¨νΈ _Imports.razorμ μ°λ¦¬κ° μμ±ν μ¬μ¬μ© κ°λ₯ν μ»΄ν¬λνΈμ μΌμΉνλ @using BlazingPizza.Sharedκ° μ΄λ―Έ ν¬ν¨λμ΄ μκΈ° λλ¬Έμ
λλ€.
OrderDetails μ»΄ν¬λνΈκ° μ£Όλ¬Έ μν μ
λ°μ΄νΈλ₯Ό μν΄ ν΄λ§ν λ μ§λμ νΌμμ μ΅μ μμΉκ° λ°μλ λ§μ»€κ° λ°μλ©λλ€.
Map μ»΄ν¬λνΈμ λν μλ°μ€ν¬λ¦½νΈ μνΈμ΄μ©μ± μ½λλ μ 곡λμμ΅λλ€. λ€μμΌλ‘λ μλ°μ€ν¬λ¦½νΈ μνΈμ΄μ©μ± μ½λλ₯Ό μΆκ°ν΄ λ³΄κ² μ΅λλ€.
μ¬μ©μκ° μ€μλ‘ μ£Όλ¬Έμμ νΌμλ₯Ό μμ νκ³ κ²°κ΅ νΌμλ₯Ό ꡬ맀νμ§ μκ² λλ€λ©΄ μνκΉμ΄ μΌμ΄ λ κ²μ λλ€. μ¬μ©μκ° νΌμλ₯Ό μμ νλ €κ³ ν λ νμΈ λ©μμ§λ₯Ό μΆκ°ν΄ λ³΄κ² μ΅λλ€. μλ°μ€ν¬λ¦½νΈ μνΈμ΄μ©μ±μ μ¬μ©νμ¬ νμΈ ν둬ννΈλ₯Ό νμνκ² μ΅λλ€.
IJSRuntimeμ Confirm νμ₯ λ©μλλ₯Ό μ¬μ©νμ¬ ν΄λΌμ΄μΈνΈ νλ‘μ νΈμ μ μ JSRuntimeExtensions ν΄λμ€λ₯Ό μΆκ°ν©λλ€. λ΄μ₯λ JavaScript confirm ν¨μλ₯Ό νΈμΆνλ €λ©΄ Confirm λ©μλλ₯Ό ꡬννμμμ€.
public static class JSRuntimeExtensions
{
public static ValueTask<bool> Confirm(this IJSRuntime jsRuntime, string message)
{
return jsRuntime.InvokeAsync<bool>("confirm", message);
}
}μλ°μ€ν¬λ¦½νΈ μνΈμ΄μ©μ± νΈμΆμ μννλ λ° μ¬μ©ν μ μλλ‘ Index κ΅¬μ± μμμ IJSRuntime μλΉμ€λ₯Ό μ½μ
ν©λλ€.
@page "/"
@inject HttpClient HttpClient
@inject OrderState OrderState
@inject NavigationManager NavigationManager
@inject IJSRuntime JSμ¬μ©μκ° μ€μ λ‘ μ£Όλ¬Έμμ νΌμλ₯Ό μ κ±°νκΈ°λ₯Ό μνλμ§ νμΈνκΈ° μν΄ Confirm λ©μλλ₯Ό νΈμΆνλ Index κ΅¬μ± μμμ λΉλκΈ° RemovePizza λ©μλλ₯Ό μΆκ°ν©λλ€.
async Task RemovePizza(Pizza configuredPizza)
{
if (await JS.Confirm($"Remove {configuredPizza.Special.Name} pizza from the order?"))
{
OrderState.RemoveConfiguredPizza(configuredPizza);
}
}Index μ»΄ν¬λνΈμμ ConfiguredPizzaItemsμ λν μ΄λ²€νΈ νΈλ€λ¬λ₯Ό μμ νμ¬ μλ‘μ΄ RemovePizza λ©μλλ₯Ό νΈμΆν©λλ€.
@foreach (var configuredPizza in OrderState.Order.Pizzas)
{
<ConfiguredPizzaItem Pizza="configuredPizza" OnRemoved="@(() => RemovePizza(configuredPizza))" />
}μ±μ μ€ννκ³ μ£Όλ¬Έμμ νΌμλ₯Ό μμ ν΄ λ³΄μΈμ.
ConfiguredPizzaItem.OnRemovedλ₯Ό λΉλκΈ°λ‘ μ€ννκΈ° μν΄ λ©μλ μκ·Έλμ²λ₯Ό μμ ν΄μΌ ν νμκ° μμ΅λλ€. EventCallbackμ λ€λ₯Έ νΉμ μμ±μΌλ‘ λκΈ°, λΉλκΈ° μ΄λ²€νΈ νΈλ€λ¬λ₯Ό λͺ¨λ μ§μν©λλ€.
λ€μ μΈμ - ν νλ¦Ώ μ»΄ν¬λνΈ
μλ¬Έ μ½κΈ° - Javascript interop

