« Blazor ASP.NET Core 7.0 » : différence entre les versions

De Banane Atomic
Aller à la navigationAller à la recherche
Ligne 44 : Ligne 44 :
<filebox fn='Pages/MyPage.razor.js'>
<filebox fn='Pages/MyPage.razor.js'>
export function myFunction() { }
export function myFunction() { }
export function myFunctionWithArg(arg) {
    return 'ok';
}
</filebox>
</filebox>


Ligne 59 : Ligne 63 :
         {
         {
             module = await JS.InvokeAsync<IJSObjectReference>("import", "./Pages/MyPage.razor.js");
             module = await JS.InvokeAsync<IJSObjectReference>("import", "./Pages/MyPage.razor.js");
            await CallMyJsFunction();
         }
         }
     }
     }


     private async Task CallMyJsFunction()
     private async Task MyJsFunction()
     {
     {
         if (module is not null)
         if (module is not null)
             await module.InvokeVoidAsync("myFunction");
             await module.InvokeVoidAsync("myFunction");
    }
    private async ValueTask<string?> MyJsFunctionWithArg(string arg)
    {
        string result = null;
        if (module is not null)
            await module.InvokeAsync<string>("myFunctionWithArg", arg);
        return result;
     }
     }



Version du 28 mars 2023 à 12:25

Pages

Pages/Items.razor
@page "/items"          @* url *@
@page "/item/{id:int}"  @* url avec un parameter *@

<PageTitle>Items</PageTitle>

@if (Items == null)  @* attendre que la valeur soit chargée *@
{
    <p><em>Loading...</em></p>
}
else
{ /* ... */ }
Pages/Items.razor.cs
public partial class Table : ComponentBase
{
    private IReadOnlyCollection<ItemDto> items;

    [Parameter]
    public int Id { get; set; }

    protected override async Task OnInitializedAsync()
    {
        items = await this.ItemClient.GetAsync();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender) { }

CSS isolation

Pages/Items.razor.css
/* scoped css only for this page */
/* @import is not allowed in scoped css */

JS isolation

Pages/MyPage.razor.js
export function myFunction() { }

export function myFunctionWithArg(arg) {
    return 'ok';
}
Pages/MyPage.razor.cs
public partial class MyPage : ComponentBase, IAsyncDisposable
{
    [Inject]
    private IJSRuntime JS { get; set; } = default!;

    private IJSObjectReference? module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import", "./Pages/MyPage.razor.js");
        }
    }

    private async Task MyJsFunction()
    {
        if (module is not null)
            await module.InvokeVoidAsync("myFunction");
    }

    private async ValueTask<string?> MyJsFunctionWithArg(string arg)
    {
        string result = null;
        if (module is not null) 
            await module.InvokeAsync<string>("myFunctionWithArg", arg);
        return result;
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
            await module.DisposeAsync();
    }
}

Form

EditItem.razor
@page "/edititem/{ItemId:int}"

<EditForm Model="@item"
          OnValidSubmit="@HandleValidSubmitAsync"
          OnInvalidSubmit="@HandleInvalidSubmitAsync">

    <button type="submit">Save</button> 
    <button @onclick="Cancel">Cancel</button>           
</EditForm>
EditItem.razor.cs
[Parameter]
public int ItemId { get; set; }

[Inject]
private IItemService ItemService { get; set; }

private Item item = null;

protected override async Task OnInitializedAsync()
{
    item = await ItemDataService.GetItemAsync(ItemId);
}

// when the submit button is clicked and the model is valid
private async Task HandleValidSubmitAsync()
{
    await ItemService.UpdateItemAsync(item);
}

// when the submit button is clicked and the model is not valid
private async Task HandleInvalidSubmitAsync() { }

Input Text

Razor.svg
<div class="form-group row">

    <label for="name"
           class="col-sm-3">
        Item: 
    </label>

    <InputText id="name"
               @bind-Value="Item.Name"
               class="form-control col-sm-8"
               placeholder="Enter name">
    </InputText>
</div>

Form validation

Data Annotation

Item.cs
[Required, StringLength(50, MinimumLength = 3, ErrorMessage = "Name must be between 3 and 50 characters")]
public string Name { get; set; }
Pages/ItemEdit.razor
<EditForm Model="@item">
    <DataAnnotationsValidator />
    <ValidationSummary />  @* affiche la liste des messages d'erreur de validation *@

    <InputText @bind-value="item.Name" 
               placeholder="Enter name" />
    <ValidationMessage class="offset-sm-3 col-sm-8" For="@(() => Item.Name)" />  @* affiche le message d'erreur de validation *@

Entity Framework Core

Using a DbContext factory

DbContext isn't thread safe and isn't designed for concurrent use.
To handle multi-threads scenarios, use a AddDbContextFactory to create a DbContext for each query.

Program.cs
builder.Services.AddDbContextFactory<MyDbContext>();
MyRepository.cs
private readonly IDbContextFactory<MyDbContext> contextFactory;

public DataSummaryRepository(IDbContextFactory<MyDbContext> contextFactory)
{
    this.contextFactory = contextFactory;
}

public async Task<Data> FetchDataAsync()
{
    // create a DbContext for this query, then dispose it once the query has been executed
    using var context = contextFactory.CreateDbContext();
}