Code Monkey home page Code Monkey logo

mvvmblazor's Introduction

MvvmBlazor

Build Status NuGet Gitter

BlazorMVVM is a small framework for building Blazor and BlazorServerside apps. With it's simple to use MVVM pattern you can boost up your development speed while minimizing the hazzle to just make it work.

Get started

MvvmBlazor is available on NuGet. You will need .NET Core 3.0 or later to use this library. The library needs to be added to the DI container in order to use it. This is done in your Startup class.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvvm();
    }
}

Usage

Components

Components need to inherit the base class MvvmBlazor.Components.MvvmComponentBase if you want to inject your view model manually. You can set a binding on any view model you like to.

If you want full support use MvvmBlazor.Components.MvvmComponentBase<T> and specify your view model type as a generic argument. Your view model will get auto injected into the component and set as a binding context.

BindingSource

The binding source is the default source object a binding will be made to. It is set automatically when using the base class MvvmBlazor.Components.MvvmComponentBase<T> where T is your view model type. You can access it via the BindingContext property in your component.

Bindings

Bindings are achieved via the Bind method in the component. If the value of the bound property has changed the component will be told to rerender automatically. In this example we assume that the class ClockViewModel has a property called DateTime.

@inherits MvvmComponentBase<ClockViewModel>

Current time: @Bind(x => x.DateTime)

Bindings can also be done by specifying the binding source explicitly:

@inherits MvvmComponentBase
@inject ClockViewModel ClockViewModel

Current time: @Bind(ClockViewModel, x => x.DateTime)

Bindings also handle background updating automatically. No need to invoke the main thread.

Collection Bininds

If you want to have a collection that automatically notifies the component when it has changed you should use one that implements INotifyCollectionChanged, e.g. ObservableCollection<T>.

In List scenarios you often chain view models to achieve bindings for every list element on it's corresponding view model. Given this view models

class MainViewModel
{
    public ObservableCollection<SubViewModel> Items { get; }
}

class SubViewModel
{
    private string _name;
    public string Name
    {
        get => _name;
        set => Set(ref, _name, value);
    }
}

you can use bindings on your sub view models like this

@foreach (var item in Bind(x => x.Items))
{
    <label>@Bind(item, x => x.Name)</label>
}

This way the name of every list item is bound to it's corresponding entry in the view. If you change the name on any list item, it will be changed in the view too.

EventHandlers

Event handles work just the way they work in blazor. When you use the non generic base class you can bind any injected object on them.

@inherits MvvmComponentBase
@inject CounterViewModel CounterViewModel

<button @onclick="@CounterViewModel.IncrementCount">Click me</button>

When using the generic base class you can directly bind them to your binding context.

@inherits MvvmComponentBase<CounterViewModel>

<button @onclick="@BindingContext.IncrementCount">Click me</button>

ViewModel

View models need to inherit the base class MvvmBlazor.ViewModel.ViewModelBase.

Property implementation

Bindable properties need to raise the PropertyChanged event on the ViewModel.

The Set-Method is performing an equality check and is raising this event if needed. An example implementation could look like this:

private int _currentCount;
public int CurrentCount
{
    get => _currentCount;
    set => Set(ref _currentCount, value);
}

Lifecycle methods

View models have access to the same lifecycle methods as a component when they are set as a binding context. They are documented here.

Parameters

Parameters are automatically populated to the view model. Declare a parameter in your component

@code {
    [Parameter]
    public string Name { get; set; }
}

and declare the same parameter in your view model

class ViewModel: ViewModelBase
{
    [Parameter]
    public string Name { get; set; }
}

The parameter will be passed before OnInitialized and OnInitializedAsync are invoked. Therefore, the parameters are available from any lifecycle method. You can't access them in your constructor and you're not supposed to do that either.

Dispose

View models are implementing the IDisposable pattern of Blazor. Inside ViewModels, Disposing is achieved by overriding the Dispose(bool disposing) method.

Examples

Examples for Blazor and Serverside Blazor can be found here.

You will find several projects in there

  • BlazorServersideSample
    A server for the blazor serverside sample
  • BlazorClientsideSample.Server
    The server for the blazor clientside sample
  • BlazorClientsideSample.Client
    The client for the blazor clientside sample

These projects act as wrapper projects for the main functionality that is shared among these examples.

  • BlazorSample.Components
    The components and pages for the samples
  • BlazorSample.ViewModels
    The view models for the pages
  • BlazorSample.Domain
    Domain logic, stuff shared between components and view models

This sample tries to incorporate a ports and adapters architectural approach and shows that this library works the same for the client and the server. It also displays the advantages of the MVVM pattern which allows you to share the logic for your frontend even when the business logic differs.

As an example the weather forecast view model just references the interface of the service that is responsible to gather data. For Blazor serverside, it directly populates it, for Blazor serverside it gathers them from an api. The advantages of such patterns will especially get interesting when Blazor Native and Blazor Embedded will be available.

Known projects

These projects are know to use MvvmBlazor. They can be used as a reference for different implementation scenarios that go beyond the samples.

If you want to see your project here, just create an issue.

mvvmblazor's People

Contributors

klemmchr avatar twsouthwick avatar

Stargazers

 avatar

Watchers

James Cloos avatar  avatar

Forkers

noname9xndz

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.