📜 ⬆️ ⬇️

DotVVM - First Look

I would like to start a series of articles on Habré about the DotVVM framework. To get started, let's start with a simple TODO list.
The framework is developed based on ASP.NET. It is easy to learn and allows you to create business applications and SPA without JavaScript code. All due to the large number of ready-made controls.
The following articles will be devoted to what started it all, what it was like to write your own framework and its support in Visual Studio, as well as what features are there in the latest release, which was released earlier this year.

For the first project I will use Visual Studio 2017 extension for DotVVM. After installing the extension, new project types should appear during creation. Choose a new DotVVM .NET Core project.



After creating a new DotVVM project, the following file structure will appear.
')


Main files


In addition, the project contains the Views and ViewModels folders. The first folder contains a file named default.dothtml, the second ViewModel folder is the DefaultViewModel.cs class. These two files together create a DotVVM web page.

DotVVM uses the Model-View-ViewModel (MVVM) pattern.

View (View) is a file with a .dothtml extension. Basically, this is an HTML file with several syntactic attributes: directives, controls, and data binding.

ViewModel is a C # class with two goals:
It contains the page status. In other words, everything that can be changed by the user on the page. If you have a TextBox on a page, you need to save its value somewhere. In DotVVM, you simply need to declare a property of type string in the ViewModel class and bind it to TextBox using the Text property.
To process the command, you simply need to declare a public method in the ViewModel .

In our list we will be able to add current affairs as plain text and check their validity when added. You can also mark things up as done.
First add the ToDoItem.cs class.

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

So, as we do not want to add empty cases without text, we will use DataAnnotations [Required] .

Add code to the View and ViewModel

ViewModel - DefaultViewModel.cs

 public class DefaultViewModel : MasterPageViewModel { //ToDoItem,     public ToDoItem ToDoItem { get; set; } = new ToDoItem(); public DefaultViewModel() { } 

View (View) - Default.dothml

  <label for="todotext">Item:</label> //   ToDoItem <dot:TextBox ID="todotext"Text="{value: ToDoItem.Text}" /> 

DotVVM works with built-in controls and their properties. <Dot: Repeater> is used for working with lists. The binding is formed through the DataSource property. In this case, all internal elements automatically change their context of the object in the list. Add a list of type List to ViewModel and Repeater to View.

ViewModel - DefaultViewModel.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> 

It remains to add features. One to add and one to mark the case in the list. Add them to the 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; } } 

In View, add two buttons <dot: Button /> . The text of the button is passed through the Text property and the execution method via Click. You can also use the IsSubmitButton property, with which the button will be pressed automatically after pressing Enter. Use this property of the button, which adds a new case to the list.

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

It remains to add a button to each case in the list, which will mark the case as done. The word “Done” should appear and the button should disappear. To bind to the DefaultViewModel context from the Repeater element, add _parent . To pass the entire object from the list, pass in the _this method.

The last property we will use in this lesson is Validation.Enabled . Validation by default works so that any postback is blocked if validation fails. In our case, a situation may arise when we want to mark a business as done, but the field with the text will remain empty. To enable postback and ignore validation when a button is pressed, we change Validation.Enabled to 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> 

There are also advanced controls, such as a GridView or FileUpload , as well as a SpaContentPlaceHolder control, which will turn a web application into a one-page application.
You can also use different types of bindings, localization of the RESX and Action filters , but more on that in the following articles.
Thanks for attention.

References:

DotVVM on github
Final project

Source: https://habr.com/ru/post/353606/


All Articles