Pull to refresh

DotVVM — Первый взгляд

Reading time 5 min
Views 4.7K
Я бы хотел начать серию статей на Хабре о фреймворке DotVVM. Для ознакомления начнем с простого TODO списка.
Фреймворк разработан на базе ASP.NET. Он прост в изучении и позволяет создавать бизнес-приложения и SPA без JavaScript кода. Все за счет большого количества готовых элементов управления.
Следующие статьи будут посвящены тому, с чего все началось, каково было писать собственный фреймворк и его поддержку в Visual Studio, а также какие фичи есть в последнем релизе, который вышел в начале этого года.

Для первого проекта я буду использовать Visual Studio 2017 расширением для DotVVM. После установки расширения при создании должны появится новые типы проектов. Выберем новый DotVVM .NET Core проект.



После создания нового DotVVM проекта, появится следующая файловая структура.



Основные файлы

  • Program.cs является основной точкой входа приложения, которое присутствует во всех .NET-приложениях .NET Core. Если вы заглянете внутрь этого файла, вы увидите, что он настраивает Kestrel, интеграцию IIS, устанавливает содержимое корневого каталога и запускает веб-хост.
  • DotvvmStartup.cs — это класс, который содержит конфигурацию для DotVVM. Вы можете найти метод ConfigureRoutes со строкой которая регистрирует маршрут по умолчанию:

    config.RouteTable.Add ("Default", "", "Views/default.dothtml");

    Если пользователь посетит домашнюю страницу, DotVVM отобразит страницу Views /default.dothtml.
  • Startup.cs содержит два метода, вызываемых при запуске приложения. Метод ConfigureServices используется для регистрации служб в объекте IServiceCollection. Понадобится вызвать services.AddDotVVM для регистрации услуг, требуемых DotVVM. Метод Configure настраивает все промежуточный слой ASP.NET. Также нужно вызвать

    app.UseDotVVM <DotvvmStartup>

    для регистрации промежуточного слоя DotVVM, которое будет обрабатывать HTTP-запросы.

Кроме того, проект содержит папки Views и ViewModels. Первая папка содержит файл с именем default.dothtml, вторая папка ViewModel класс DefaultViewModel.cs. Эти два файла вместе создают веб-страницу DotVVM.

DotVVM использует паттерн Model-View-ViewModel (MVVM).

View (Представление) — это файл с расширением .dothtml. В принципе, это HTML-файл с несколькими синтаксическими атрибутами: директивы, элементами управления и привязки данных.

ViewModel — это класс C# с двумя целями:
Он содержит состояние страницы. Другими словами, все, что может быть изменено пользователем на странице. Если у вас есть TextBox на странице, вам нужно где-то сохранить его значение. В DotVVM вам просто нужно объявить свойство типа string в классе ViewModel и привязать ее к TextBox при помощи свойства Text.
Для обработки команды нужно просто объявить публичный метод в ViewModel.

В наш список мы сможем добавлять текущие дела как обычный текст и проверять их валидность при добавлении. Также дела можно будет отмечать их как сделаные.
Сначала добавим ToDoItem.cs класс.


    public class ToDoItem
    {
        [Required]
        public string Text { get; set; }

        public bool IsDone { get; set; }
    }

Так, как мы не хотим добавлять пустые дела без текста, мы будем использовать DataAnnotations [Required].

Добавим код в View и ViewModel

ViewModelDefaultViewModel.cs


public class DefaultViewModel : MasterPageViewModel
    {
//ToDoItem, который мы будем добавлять
        public ToDoItem ToDoItem { get; set; } = new ToDoItem();
        public DefaultViewModel()
        {
        }

Представление (View)Default.dothml

   <label for="todotext">Item:</label>
   
   //привязка к тексту ToDoItem
    <dot:TextBox  ID="todotext"Text="{value: ToDoItem.Text}" />

В DotVVM работает со встроенными элементами управления и их свойствами. Для работы со списками используется <dot:Repeater>. Привязка образуется через свойство DataSource. При этом все внутренние элементы автоматически изменят свой контекст объекта в списке. Добавим список типа List в ViewModel и Repeater в View.

ViewModelDefaultViewModel.cs


public class DefaultViewModel : MasterPageViewModel
    {
        //ToDoItem, который мы будем добавлять
        public ToDoItem ToDoItem { get; set; } = new ToDoItem();

        public List<ToDoItem> ToDoItems { get; set; } = new List<ToDoItem>();

        public DefaultViewModel()
        {
        }
    }

    <label for="todotext">Item:</label>
    
    //привязка к тексту ToDoItem
    <dot:TextBox  ID="todotext"Text="{value: ToDoItem.Text}" />

     <hr />
     <dot:Repeater DataSource="{value: ToDoItems}">
            <span>{{value: Text}}</span>
            <span Visible="{value: IsDone}">Done!</span>
     </dot:Repeater>

 

Осталось добавить функции. Одну для добавления и одну для пометки дела в списке. Добавим их в ViewModel.


    public class DefaultViewModel : MasterPageViewModel
        {
            //ToDoItem, который мы будем добавлять
            public ToDoItem ToDoItem { get; set; } = new ToDoItem();
    
            public List<ToDoItem> ToDoItems { get; set; } = new List<ToDoItem>();
    
            public DefaultViewModel()
            {
            }

            public void AddTodoItem(ToDoItem item)
            {
                ToDoItems.Add(ToDoItem);
                ToDoItem = new ToDoItem();
            }
    
            public void MarkAsDone(ToDoItem item)
            {
                item.IsDone = true;
            }
        }

В View добавим две кнопки <dot:Button/>. Текст кнопки передается через свойство Text а метод выполнения через Click. Также можно использовать свойство IsSubmitButton, при помощи которого кнопка будет нажиматься автоматически после нажатия Enter. Используем это свойство у кнопки, которая добавляет новое дело в список.

    <label for="todotext">Item:</label>
    
    //привязка к тексту ToDoItem
    <dot:TextBox  ID="todotext"Text="{value: ToDoItem.Text}" />

     <dot:Button Text="Add Item" IsSubmitButton="true" Click="{command: AddTodoItem(ToDoItem)}"></dot:Button>

     <hr />
     <dot:Repeater DataSource="{value: ToDoItems}">
            <span>{{value: Text}}</span>
            <span Visible="{value: IsDone}">Done!</span>
     </dot:Repeater>

 

Осталось к каждому делу в списке добавить кнопку, которая обозначит дело как сделанное. Должна отобразится надпись «Done» а кнопка должна исчезнуть. Чтобы сделать привязку в контекст DefaultViewModel из елемента Repeater, добавим _parent. Чтобы передать весь обьект из списка, передадим в метод _this.

Последнее свойство, которое мы будем использовать в этом уроке, это Validation.Enabled. Валидация по умолчанию работает так, что любой постбэк блокируется если валидация не проходит. В нашем случае может возникнуть ситуация, когда мы захотим пометить дело как сделанное, но поле с текстом останется пустым. Чтобы разрешить постбэк и игнорировать валидацию при нажатии кнопки, изменим Validation.Enabled на значение false.

   <label for="todotext">Item:</label>
    
    //привязка к тексту ToDoItem
    <dot:TextBox  ID="todotext"Text="{value: ToDoItem.Text}" />

     <dot:Button Text="Add Item" IsSubmitButton="true" Click="{command: AddTodoItem(ToDoItem)}"></dot:Button>

     <hr />
     <dot:Repeater DataSource="{value: ToDoItems}">
            <span>{{value: Text}}</span>
            <p><dot:Button Validation.Enabled="false" Visible="{value: !IsDone}" Text="Mark as done" Click="{command: _parent.MarkAsDone(_this)}"></dot:Button></p>
        <hr />
     </dot:Repeater>

 

Существуют также расширенные средства управления, такие как GridView или FileUpload, а также элемент управления SpaContentPlaceHolder, который превратит веб-приложение в Одностраничное приложение.
Вы также можете использовать разные типы привязок, локализацию RESX и Action фильтры, но об этом в следующих статьях.
Спасибо за внимание.

Ссылки:

DotVVM на GitHub
Финальный проект
Tags:
Hubs:
+1
Comments 16
Comments Comments 16

Articles