Здесь также есть другое решение, подобное точке Луи Хендрика , которое:
Вы можете использовать наследуемый код и внедренную ViewModel на
тот же Razor View, если у вас есть необходимость или если вы хотите сохранить страницу
код жизненного цикла отдельно от привязок данных.
Рассматривать 'состояние' как альтернативу моделям вида
В мире React / Redux / Flux часто обсуждается понятие «Состояние», которое относится к объекту (или объектам), который содержит весь статус приложения или областей приложения) в определенный момент времени. , В представлении Flux о мире каждое действие в приложении переводит приложение из его существующего состояния в новое состояние.
Состояние приложения состоит из текущих значений данных (например, скажем, contact.firstname
), а также состояния пользовательского интерфейса (например, включена ли эта кнопка).
Это достигается в основном тем же способом, что и подход ViewModel, но подход State часто группирует код по поведению (например, все состояния, связанные с заказом Pizza, так, из чего состоит текущая Pizza, а также какие элементы пользовательского интерфейса должны отображаться, если заказ обрабатывается) и признает, что состояние может отображаться несколькими компонентами, поэтому объекты состояния не обязательно будут отображаться напрямую в один файл бритвы, как это обычно делает ViewModel.
Отличный пример и учебное пособие, предоставлено командой .NET
Это проще с примером, и, к счастью, мастерская блейзора Blazing Pizza команды Microsoft Blazor обеспечивает превосходный результат.
В качестве быстрого примера из этого урока - это OrderState
класс , в котором хранится текущее состояние, относящееся к текущему порядку:
public class OrderState
{
public event EventHandler StateChanged;
public bool ShowingConfigureDialog { get; private set; }
public Pizza ConfiguringPizza { get; private set; }
public Order Order { get; private set; } = new Order();
public void ShowConfigurePizzaDialog(PizzaSpecial special)
{
ConfiguringPizza = new Pizza()
{
Special = special,
SpecialId = special.Id,
Size = Pizza.DefaultSize,
Toppings = new List<PizzaTopping>(),
};
ShowingConfigureDialog = true;
}
public void CancelConfigurePizzaDialog()
{
ConfiguringPizza = null;
ShowingConfigureDialog = false;
StateHasChanged();
}
public void ConfirmConfigurePizzaDialog()
{
Order.Pizzas.Add(ConfiguringPizza);
ConfiguringPizza = null;
ShowingConfigureDialog = false;
StateHasChanged();
}
public void RemoveConfiguredPizza(Pizza pizza)
{
Order.Pizzas.Remove(pizza);
StateHasChanged();
}
public void ResetOrder()
{
Order = new Order();
}
private void StateHasChanged()
{
StateChanged?.Invoke(this, EventArgs.Empty);
}
} ```
Обратите внимание, что в этом классе состояний нет концепции связанного с ним пользовательского интерфейса, но у него есть свойства, которые управляют поведением пользовательского интерфейса.
В этом примере классы-бритвы все еще имеют блоки @functions, но они значительно упрощаются благодаря введению свойств в классе State, которые играют явную роль в управлении поведением пользовательского интерфейса (например, ShowingConfigureDialog
). Например, из index.razor :
<ul class="pizza-cards">
@if (specials != null)
{
@foreach (var special in specials)
{
<li onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))"
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> ```
Весь этот учебник превосходен, я настоятельно рекомендую поработать над ним.
Но я не хочу код C # в моих файлах бритвы ...
Вы все еще можете поместить код из блока @functions в файл базового класса, а также использовать подход состояния.
Причина, по которой люди склонны этого не делать, заключается в том, что если ваш файл состояния управляет поведением пользовательского интерфейса, тогда код проводки @functions
обычно заканчивается в виде нескольких строк, поэтому часто кажется, что его не стоит помещать в отдельный файл.