ASP.NET Core Blazor cykl życiaASP.NET Core Blazor lifecycle

BlazorPlatforma obejmuje metody cyklu życia synchronicznego i asynchronicznego.The Blazor framework includes synchronous and asynchronous lifecycle methods. Zastąp metody cyklu życia, aby wykonać dodatkowe operacje na składnikach podczas inicjowania i renderowania składnika.Override lifecycle methods to perform additional operations on components during component initialization and rendering.

Poniższe diagramy ilustrują Blazor cykl życia.The following diagrams illustrate the Blazor lifecycle. Metody cyklu życia są definiowane przy użyciu przykładów w poniższych sekcjach tego artykułu.Lifecycle methods are defined with examples in the following sections of this article.

Zdarzenia cyklu życia składnika:Component lifecycle events:

  1. Jeśli składnik jest renderowany po raz pierwszy w żądaniu:If the component is rendering for the first time on a request:
    • Utwórz wystąpienie składnika.Create the component's instance.
    • Wykonaj iniekcję właściwości.Perform property injection. Uruchom SetParametersAsync .Run SetParametersAsync.
    • Wywołanie OnInitialized{Async} .Call OnInitialized{Async}. W przypadku Task zwrócenia elementu Task jest oczekiwany, a składnik jest renderowany.If a Task is returned, the Task is awaited and the component is rendered. Jeśli element Task nie jest zwracany, składnik jest renderowany.If a Task isn't returned, the component is rendered.
  2. Wywołaj OnParametersSet{Async} i Renderuj składnik.Call OnParametersSet{Async} and render the component. Jeśli Task jest zwracany z OnParametersSetAsync , Task jest oczekiwany, a następnie składnik jest ponownie renderowany.If a Task is returned from OnParametersSetAsync, the Task is awaited and then the component is rerendered.

Zdarzenia cyklu życia składnika::: No-Loc (Razor)::: składnik w::: No-Loc (Blazor)::

Przetwarzanie zdarzeń w Document Object Model (DOM):Document Object Model (DOM) event processing:

  1. Procedura obsługi zdarzeń jest uruchamiana.The event handler is run.
  2. W przypadku Task zwrócenia elementu Task jest oczekiwany, a następnie jest renderowany składnik.If a Task is returned, the Task is awaited and then the component is rendered. Jeśli element Task nie jest zwracany, składnik jest renderowany.If a Task isn't returned, the component is rendered.

Przetwarzanie zdarzeń Document Object Model (DOM)

RenderCykl życia:The Render lifecycle:

  1. Unikaj dalszych operacji renderowania na składniku:Avoid further rendering operations on the component:
  2. Kompiluj porównanie drzewa renderowania (różnica) i Renderuj składnik.Build the render tree diff (difference) and render the component.
  3. Oczekiwanie na zaktualizowanie modelu DOM.Await the DOM to update.
  4. Wywołanie OnAfterRender{Async} .Call OnAfterRender{Async}.

Cykl życia renderowania

Deweloperzy mogą wykonywać wywołania StateHasChanged w wyniku.Developer calls to StateHasChanged result in a render. Aby uzyskać więcej informacji, zobacz BlazorRenderowanie składników ASP.NET Core.For more information, see BlazorRenderowanie składników ASP.NET Core.

Metody cyklu życiaLifecycle methods

Przed ustawieniem parametrówBefore parameters are set

SetParametersAsync Ustawia parametry dostarczone przez element nadrzędny składnika w drzewie renderowania lub z parametrów trasy.SetParametersAsync sets parameters supplied by the component's parent in the render tree or from route parameters. Zastępując metodę, kod dewelopera może współdziałać bezpośrednio z ParameterView parametrami.By overriding the method, developer code can interact directly with the ParameterView's parameters.

W poniższym przykładzie ParameterView.TryGetValue przypisuje Param wartość parametru do, value Jeśli analizowanie parametru trasy dla programu Param zakończyło się pomyślnie.In the following example, ParameterView.TryGetValue assigns the Param parameter's value to value if parsing a route parameter for Param is successful. Gdy value nie jest null , wartość jest wyświetlana przez składnik.When value isn't null, the value is displayed by the component.

Chociaż dopasowanie parametrów trasy nie uwzględnia wielkości liter, TryGetValue w szablonie trasy są uwzględniane tylko nazwy parametrów z uwzględnieniem wielkości liter.Although route parameter matching is case insensitive, TryGetValue only matches case sensitive parameter names in the route template. Poniższy przykład jest wymagany do korzystania z /{Param?} nie, aby /{param?} można było pobrać wartość.The following example is required to use /{Param?}, not /{param?}, in order to get the value. Jeśli /{param?} jest używana w tym scenariuszu, TryGetValue zwraca false i message nie jest ustawiona na ciąg.If /{param?} is used in this scenario, TryGetValue returns false and message isn't set to either string.

Pages/SetParametersAsyncExample.razor:Pages/SetParametersAsyncExample.razor:

@page "/setparametersasync-example/{Param?}"

<h1>SetParametersAsync Example</h1>

<p>@message</p>

@code {
    private string message;

    [Parameter]
    public string Param { get; set; }

    public override async Task SetParametersAsync(ParameterView parameters)
    {
        if (parameters.TryGetValue<string>(nameof(Param), out var value))
        {
            if (value is null)
            {
                message = "The value of 'Param' is null.";
            }
            else
            {
                message = $"The value of 'Param' is {value}.";
            }
        }

        await base.SetParametersAsync(parameters);
    }
}

ParameterView zawiera zestaw wartości parametrów dla składnika, gdy SetParametersAsync jest wywoływana.ParameterView contains the set of parameter values for the component each time SetParametersAsync is called.

Domyślna implementacja programu SetParametersAsync ustawia wartość każdej właściwości z [Parameter] [CascadingParameter] atrybutem lub, który ma odpowiednią wartość w ParameterView .The default implementation of SetParametersAsync sets the value of each property with the [Parameter] or [CascadingParameter] attribute that has a corresponding value in the ParameterView. Parametry, które nie mają odpowiedniej wartości w, ParameterView pozostają bez zmian.Parameters that don't have a corresponding value in ParameterView are left unchanged.

Jeśli base.SetParametersAsync nie zostanie wywołana, kod niestandardowy może interpretować wartość parametrów przychodzących w dowolny sposób.If base.SetParametersAsync isn't invoked, the custom code can interpret the incoming parameters value in any way required. Na przykład nie jest wymagane przypisanie parametrów przychodzących do właściwości w klasie.For example, there's no requirement to assign the incoming parameters to the properties on the class.

W przypadku skonfigurowania dowolnych programów obsługi zdarzeń odłączanie ich do usunięcia.If any event handlers are set up, unhook them on disposal. Aby uzyskać więcej informacji, zobacz sekcję Usuwanie składnika IDisposable z .For more information, see the Component disposal with IDisposable section.

Metody inicjujące składnikiComponent initialization methods

OnInitializedAsync i OnInitialized są wywoływane, gdy składnik zostanie zainicjowany po odebraniu początkowych parametrów z jego składnika nadrzędnego w SetParametersAsync .OnInitializedAsync and OnInitialized are invoked when the component is initialized after having received its initial parameters from its parent component in SetParametersAsync.

Użyj OnInitializedAsync , gdy składnik wykonuje operację asynchroniczną i powinien być odświeżany po zakończeniu operacji.Use OnInitializedAsync when the component performs an asynchronous operation and should refresh when the operation is completed.

W przypadku operacji synchronicznej Przesłoń OnInitialized :For a synchronous operation, override OnInitialized:

protected override void OnInitialized()
{
    ...
}

Aby wykonać operację asynchroniczną, Przesłoń OnInitializedAsync i Użyj await operatora dla operacji:To perform an asynchronous operation, override OnInitializedAsync and use the await operator on the operation:

protected override async Task OnInitializedAsync()
{
    await ...
}

Blazor Serveraplikacje, które dwukrotnie wywołują swoje wywołanie zawartości OnInitializedAsync :Blazor Server apps that prerender their content call OnInitializedAsync twice:

  • Gdy składnik jest początkowo renderowany statycznie jako część strony.Once when the component is initially rendered statically as part of the page.
  • Drugi raz, gdy przeglądarka nawiąże połączenie z serwerem.A second time when the browser establishes a connection back to the server.

Aby zapobiec OnInitializedAsync dwukrotnemu uruchomieniu kodu dewelopera, zapoznaj się z sekcją ponowne łączenie po prerenderowania .To prevent developer code in OnInitializedAsync from running twice, see the Stateful reconnection after prerendering section.

Podczas gdy Blazor Server aplikacja jest wstępnie renderowana, niektóre akcje, takie jak wywoływanie kodu JavaScript, nie są możliwe, ponieważ połączenie z przeglądarką nie zostało nawiązane.While a Blazor Server app is prerendering, certain actions, such as calling into JavaScript, aren't possible because a connection with the browser hasn't been established. Składniki mogą być konieczne w różny sposób, gdy są wstępnie renderowane.Components may need to render differently when prerendered. Aby uzyskać więcej informacji, zobacz sekcję wykrywanie, gdy aplikacja jest prerenderowana .For more information, see the Detect when the app is prerendering section.

W przypadku skonfigurowania dowolnych programów obsługi zdarzeń odłączanie ich do usunięcia.If any event handlers are set up, unhook them on disposal. Aby uzyskać więcej informacji, zobacz sekcję Usuwanie składnika IDisposable z .For more information, see the Component disposal with IDisposable section.

Po ustawieniu parametrówAfter parameters are set

OnParametersSetAsync lub OnParametersSet są wywoływane:OnParametersSetAsync or OnParametersSet are called:

  • Po zainicjowaniu składnika w programie OnInitialized lub OnInitializedAsync .After the component is initialized in OnInitialized or OnInitializedAsync.
  • Po ponownym wyrenderowaniu i zaopatrzeniu składnika nadrzędnego:When the parent component re-renders and supplies:
    • Tylko znane niezmienne typy pierwotne, których co najmniej jeden parametr został zmieniony.Only known primitive immutable types of which at least one parameter has changed.
    • Wszystkie parametry złożone z typem.Any complex-typed parameters. Struktura nie może wiedzieć, czy wartości parametru złożonego są mutacją wewnętrznie, dlatego traktuje zestaw parametrów jako zmieniony.The framework can't know whether the values of a complex-typed parameter have mutated internally, so it treats the parameter set as changed.
protected override async Task OnParametersSetAsync()
{
    await ...
}

Uwaga

Asynchroniczna działanie, gdy stosowane są parametry i wartości właściwości, muszą wystąpić podczas OnParametersSetAsync zdarzenia cyklu życia.Asynchronous work when applying parameters and property values must occur during the OnParametersSetAsync lifecycle event.

protected override void OnParametersSet()
{
    ...
}

W przypadku skonfigurowania dowolnych programów obsługi zdarzeń odłączanie ich do usunięcia.If any event handlers are set up, unhook them on disposal. Aby uzyskać więcej informacji, zobacz sekcję Usuwanie składnika IDisposable z .For more information, see the Component disposal with IDisposable section.

Po renderowania składnikówAfter component render

OnAfterRenderAsync i OnAfterRender są wywoływane po zakończeniu renderowania składnika.OnAfterRenderAsync and OnAfterRender are called after a component has finished rendering. Odwołania do elementów i składników są wypełniane w tym momencie.Element and component references are populated at this point. Ten etap służy do wykonywania dodatkowych kroków inicjowania przy użyciu renderowanej zawartości, takiej jak aktywacja bibliotek języka JavaScript innych firm, które działają na renderowanych elementach DOM.Use this stage to perform additional initialization steps using the rendered content, such as activating third-party JavaScript libraries that operate on the rendered DOM elements.

firstRenderParametr dla OnAfterRenderAsync i OnAfterRender :The firstRender parameter for OnAfterRenderAsync and OnAfterRender:

  • Jest ustawiany po true raz pierwszy, gdy wystąpienie składnika jest renderowane.Is set to true the first time that the component instance is rendered.
  • Można go użyć, aby upewnić się, że zadania inicjowania są wykonywane tylko raz.Can be used to ensure that initialization work is only performed once.
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await ...
    }
}

Uwaga

Asynchroniczne działanie natychmiast po wyrenderowaniu musi wystąpić w trakcie OnAfterRenderAsync zdarzenia cyklu życia.Asynchronous work immediately after rendering must occur during the OnAfterRenderAsync lifecycle event.

Nawet w przypadku powrotu Task z programu OnAfterRenderAsync , struktura nie planuje dalszych cykli renderowania dla składnika po zakończeniu tego zadania.Even if you return a Task from OnAfterRenderAsync, the framework doesn't schedule a further render cycle for your component once that task completes. Ma to na celu uniknięcie nieskończonej pętli renderowania.This is to avoid an infinite render loop. Różnią się one od innych metod cyklu życia, które Zaplanuj kolejny cykl renderowania po zakończeniu zwracanego zadania.It's different from the other lifecycle methods, which schedule a further render cycle once the returned task completes.

protected override void OnAfterRender(bool firstRender)
{
    if (firstRender)
    {
        ...
    }
}

OnAfterRender i OnAfterRenderAsync nie są wywoływane podczas procesu renderowania wstępnego na serwerze.OnAfterRender and OnAfterRenderAsync aren't called during the prerendering process on the server. Metody są wywoływane, gdy składnik jest renderowany interaktywnie po zakończeniu renderowania prerenderingu.The methods are called when the component is rendered interactively after prerendering is finished. Gdy aplikacja jest przedrenderowana:When the app prerenders:

  1. Składnik jest wykonywany na serwerze w celu utworzenia statycznego znacznika HTML w odpowiedzi HTTP.The component executes on the server to produce some static HTML markup in the HTTP response. W tej fazie OnAfterRender i OnAfterRenderAsync nie są wywoływane.During this phase, OnAfterRender and OnAfterRenderAsync aren't called.
  2. Kiedy blazor.server.js lub blazor.webassembly.js uruchamiasz w przeglądarce, składnik jest uruchamiany ponownie w trybie renderowania interaktywnego.When blazor.server.js or blazor.webassembly.js start up in the browser, the component is restarted in an interactive rendering mode. Po ponownym uruchomieniu składnika OnAfterRender i OnAfterRenderAsync wywoływane, ponieważ aplikacja nie znajduje się w fazie renderowania prerenderingu.After a component is restarted, OnAfterRender and OnAfterRenderAsync are called because the app isn't inside the prerendering phase any longer.

W przypadku skonfigurowania dowolnych programów obsługi zdarzeń odłączanie ich do usunięcia.If any event handlers are set up, unhook them on disposal. Aby uzyskać więcej informacji, zobacz sekcję Usuwanie składnika IDisposable z .For more information, see the Component disposal with IDisposable section.

Pomiń odświeżanie interfejsu użytkownikaSuppress UI refreshing

Przesłoń ShouldRender , aby pominąć odświeżanie interfejsu użytkownika.Override ShouldRender to suppress UI refreshing. Jeśli implementacja zwraca true , interfejs użytkownika zostanie odświeżony:If the implementation returns true, the UI is refreshed:

protected override bool ShouldRender()
{
    var renderUI = true;

    return renderUI;
}

ShouldRender jest wywoływana za każdym razem, gdy składnik jest renderowany.ShouldRender is called each time the component is rendered.

Nawet jeśli ShouldRender jest zastępowany, składnik jest zawsze początkowo renderowany.Even if ShouldRender is overridden, the component is always initially rendered.

Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor WebAssembly najlepszych rozwiązań dotyczących wydajności.For more information, see ASP.NET Core Blazor WebAssembly najlepszych rozwiązań dotyczących wydajności.

Zmiany stanuState changes

StateHasChanged powiadamia składnik o zmianie stanu.StateHasChanged notifies the component that its state has changed. Jeśli ma to zastosowanie, wywołanie StateHasChanged powoduje, że składnik jest renderowany.When applicable, calling StateHasChanged causes the component to be rerendered.

StateHasChanged jest wywoływana automatycznie dla EventCallback metod.StateHasChanged is called automatically for EventCallback methods. Aby uzyskać więcej informacji, zobacz BlazorObsługa zdarzeń ASP.NET Core.For more information, see BlazorObsługa zdarzeń ASP.NET Core.

Aby uzyskać więcej informacji, zobacz BlazorRenderowanie składników ASP.NET Core.For more information, see BlazorRenderowanie składników ASP.NET Core.

Obsługuj niekompletne akcje asynchroniczne podczas renderowaniaHandle incomplete async actions at render

Akcje asynchroniczne wykonane w zdarzeniach cyklu życia mogły nie zostać ukończone przed renderowaniem składnika.Asynchronous actions performed in lifecycle events might not have completed before the component is rendered. Obiekty mogą być null lub uzupełniane wypełniane danymi podczas wykonywania metody cyklu życia.Objects might be null or incompletely populated with data while the lifecycle method is executing. Zapewnianie logiki renderowania w celu potwierdzenia, że obiekty są inicjowane.Provide rendering logic to confirm that objects are initialized. Renderuj zastępcze elementy interfejsu użytkownika (na przykład komunikat ładowania), gdy obiekty są null .Render placeholder UI elements (for example, a loading message) while objects are null.

W FetchData składniku Blazor szablonów program OnInitializedAsync jest zastępowany asynchronicznie odbieranych danych prognozy ( forecasts ).In the FetchData component of the Blazor templates, OnInitializedAsync is overridden to asynchronously receive forecast data (forecasts). Gdy forecasts tak jest null , zostanie wyświetlony komunikat ładowania użytkownika.When forecasts is null, a loading message is displayed to the user. Po Task zakończeniu zwracany przez OnInitializedAsync program składnik zostanie przerenderowany ze zaktualizowanym stanem.After the Task returned by OnInitializedAsync completes, the component is rerendered with the updated state.

Pages/FetchData.razor w Blazor Server szablonie:Pages/FetchData.razor in the Blazor Server template:

@page "/fetchdata"
@using MyBlazorApp.Data
@inject WeatherForecastService ForecastService

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from a service.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <!-- forecast data in table element content -->
    </table>
}

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }
}

Obsługa błędówHandle errors

Aby uzyskać informacje na temat obsługi błędów podczas wykonywania metody cyklu życia, zobacz Obsługa błędów w Blazor aplikacjach ASP.NET Core .For information on handling errors during lifecycle method execution, see Obsługa błędów w Blazor aplikacjach ASP.NET Core.

Stanowe Ponowne nawiązywanie połączenia po przeprowadzeniu prerenderowaniaStateful reconnection after prerendering

W Blazor Server aplikacji, gdy RenderMode jest ServerPrerendered , składnik jest początkowo renderowany statycznie jako część strony.In a Blazor Server app when RenderMode is ServerPrerendered, the component is initially rendered statically as part of the page. Gdy przeglądarka nawiąże połączenie z serwerem, składnik jest renderowany ponownie, a składnik jest teraz interaktywny.Once the browser establishes a connection back to the server, the component is rendered again, and the component is now interactive. Jeśli OnInitialized{Async} istnieje metoda cyklu życia do inicjowania składnika, metoda jest wykonywana dwukrotnie:If the OnInitialized{Async} lifecycle method for initializing the component is present, the method is executed twice:

  • Gdy składnik jest wstępnie renderowany statycznie.When the component is prerendered statically.
  • Po nawiązaniu połączenia z serwerem.After the server connection has been established.

Może to spowodować zauważalną zmianę danych wyświetlanych w interfejsie użytkownika, gdy składnik jest renderowany.This can result in a noticeable change in the data displayed in the UI when the component is finally rendered.

Aby uniknąć podwójnego renderowania w Blazor Server aplikacji:To avoid the double-rendering scenario in a Blazor Server app:

  • Przekaż identyfikator, który może służyć do buforowania stanu podczas wykonywania prerenderowania i pobierania stanu po ponownym uruchomieniu aplikacji.Pass in an identifier that can be used to cache the state during prerendering and to retrieve the state after the app restarts.
  • Użyj identyfikatora podczas renderowania, aby zapisać stan składnika.Use the identifier during prerendering to save component state.
  • Użyj identyfikatora po włączeniu, aby pobrać buforowany stan.Use the identifier after prerendering to retrieve the cached state.

Poniższy kod ilustruje aktualizację WeatherForecastService w aplikacji opartej na szablonie Blazor Server , która pozwala uniknąć podwójnego renderowania:The following code demonstrates an updated WeatherForecastService in a template-based Blazor Server app that avoids the double rendering:

public class WeatherForecastService
{
    private static readonly string[] summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild",
        "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };
    
    public WeatherForecastService(IMemoryCache memoryCache)
    {
        MemoryCache = memoryCache;
    }
    
    public IMemoryCache MemoryCache { get; }

    public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
    {
        return MemoryCache.GetOrCreateAsync(startDate, async e =>
        {
            e.SetOptions(new MemoryCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = 
                    TimeSpan.FromSeconds(30)
            });

            var rng = new Random();

            await Task.Delay(TimeSpan.FromSeconds(10));

            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = summaries[rng.Next(summaries.Length)]
            }).ToArray();
        });
    }
}

Aby uzyskać więcej informacji na temat RenderMode , zobacz Blazor SignalR Wskazówki dotyczące ASP.NET Core .For more information on the RenderMode, see Blazor SignalR Wskazówki dotyczące ASP.NET Core.

Wykryj, kiedy aplikacja jest przedrenderowanaDetect when the app is prerendering

Podczas gdy Blazor Server aplikacja jest wstępnie renderowana, niektóre akcje, takie jak wywoływanie kodu JavaScript, nie są możliwe, ponieważ połączenie z przeglądarką nie zostało nawiązane.While a Blazor Server app is prerendering, certain actions, such as calling into JavaScript, aren't possible because a connection with the browser hasn't been established. Składniki mogą być konieczne w różny sposób, gdy są wstępnie renderowane.Components may need to render differently when prerendered.

Aby opóźnić wywołania międzyoperacyjne języka JavaScript do momentu ustanowienia połączenia z przeglądarką, można użyć zdarzenia cyklu życia składnika OnAfterRenderAsync.To delay JavaScript interop calls until after the connection with the browser is established, you can use the OnAfterRenderAsync component lifecycle event. To zdarzenie jest wywoływane tylko wtedy, gdy aplikacja jest w pełni renderowana, a połączenie z klientem zostanie nawiązane.This event is only called after the app is fully rendered and the client connection is established.

@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime

<div @ref="divElement">Text during render</div>

@code {
    private ElementReference divElement;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync(
                "setElementText", divElement, "Text after render");
        }
    }
}

W powyższym przykładowym kodzie Podaj setElementText funkcję JavaScript wewnątrz <head> elementu wwwroot/index.html ( Blazor WebAssembly ) lub Pages/_Host.cshtml ( Blazor Server ).For the preceding example code, provide a setElementText JavaScript function inside the <head> element of wwwroot/index.html (Blazor WebAssembly) or Pages/_Host.cshtml (Blazor Server). Funkcja jest wywoływana z JSRuntimeExtensions.InvokeVoidAsync i nie zwraca wartości:The function is called with JSRuntimeExtensions.InvokeVoidAsync and doesn't return a value:

<script>
  window.setElementText = (element, text) => element.innerText = text;
</script>

Ostrzeżenie

Poprzedni przykład modyfikuje Document Object Model (DOM) bezpośrednio wyłącznie w celach demonstracyjnych.The preceding example modifies the Document Object Model (DOM) directly for demonstration purposes only. Nie zaleca się bezpośredniej modyfikacji modelu DOM przy użyciu języka JavaScript w większości scenariuszy, ponieważ kod JavaScript może zakłócać Blazor śledzenie zmian.Directly modifying the DOM with JavaScript isn't recommended in most scenarios because JavaScript can interfere with Blazor's change tracking.

Poniższy składnik pokazuje, jak używać międzyoperacyjności JavaScript jako części logiki inicjalizacji składnika w sposób, który jest zgodny z renderowaniem.The following component demonstrates how to use JavaScript interop as part of a component's initialization logic in a way that's compatible with prerendering. Składnik pokazuje, że można wyzwolić aktualizację renderowania z wewnątrz OnAfterRenderAsync .The component shows that it's possible to trigger a rendering update from inside OnAfterRenderAsync. Deweloper musi unikać tworzenia pętli nieskończonej w tym scenariuszu.The developer must avoid creating an infinite loop in this scenario.

Gdzie JSRuntime.InvokeAsync jest wywoływana, ElementRef jest używana tylko w, OnAfterRenderAsync a nie w żadnej wcześniejszej metodzie cyklu życia, ponieważ nie istnieje element JavaScript do momentu renderowania składnika.Where JSRuntime.InvokeAsync is called, ElementRef is only used in OnAfterRenderAsync and not in any earlier lifecycle method because there's no JavaScript element until after the component is rendered.

StateHasChanged jest wywoływana, aby przetworzyć składnik z nowym stanem uzyskanym z wywołania międzyoperacyjności JavaScript (Aby uzyskać więcej informacji, zobacz BlazorRenderowanie składników ASP.NET Core ).StateHasChanged is called to rerender the component with the new state obtained from the JavaScript interop call (for more information, see BlazorRenderowanie składników ASP.NET Core). Kod nie tworzy pętli nieskończonej, ponieważ StateHasChanged jest wywoływana tylko wtedy, gdy infoFromJs jest null .The code doesn't create an infinite loop because StateHasChanged is only called when infoFromJs is null.

@page "/prerendered-interop"
@using Microsoft.AspNetCore.Components
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime

<p>
    Get value via JS interop call:
    <strong id="val-get-by-interop">@(infoFromJs ?? "No value yet")</strong>
</p>

Set value via JS interop call:
<div id="val-set-by-interop" @ref="divElement"></div>

@code {
    private string infoFromJs;
    private ElementReference divElement;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender && infoFromJs == null)
        {
            infoFromJs = await JSRuntime.InvokeAsync<string>(
                "setElementText", divElement, "Hello from interop call!");

            StateHasChanged();
        }
    }
}

W powyższym przykładowym kodzie Podaj setElementText funkcję JavaScript wewnątrz <head> elementu wwwroot/index.html ( Blazor WebAssembly ) lub Pages/_Host.cshtml ( Blazor Server ).For the preceding example code, provide a setElementText JavaScript function inside the <head> element of wwwroot/index.html (Blazor WebAssembly) or Pages/_Host.cshtml (Blazor Server). Funkcja jest wywoływana z IJSRuntime.InvokeAsync i zwraca wartość:The function is called withIJSRuntime.InvokeAsync and returns a value:

<script>
  window.setElementText = (element, text) => {
    element.innerText = text;
    return text;
  };
</script>

Ostrzeżenie

Poprzedni przykład modyfikuje Document Object Model (DOM) bezpośrednio wyłącznie w celach demonstracyjnych.The preceding example modifies the Document Object Model (DOM) directly for demonstration purposes only. Nie zaleca się bezpośredniej modyfikacji modelu DOM przy użyciu języka JavaScript w większości scenariuszy, ponieważ kod JavaScript może zakłócać Blazor śledzenie zmian.Directly modifying the DOM with JavaScript isn't recommended in most scenarios because JavaScript can interfere with Blazor's change tracking.

Usuwanie składnika z IDisposableComponent disposal with IDisposable

Jeśli składnik implementuje IDisposable , struktura wywołuje metodę usuwania po usunięciu składnika z interfejsu użytkownika, w którym można wydać niezarządzane zasoby.If a component implements IDisposable, the framework calls the disposal method when the component is removed from the UI, where unmanaged resources can be released. Usuwanie może odbywać się w dowolnym momencie, w tym podczas inicjowania składnika.Disposal can occur at any time, including during component initialization. Następujący składnik implementuje IDisposable z @implements Razor dyrektywą:The following component implements IDisposable with the @implements Razor directive:

@using System
@implements IDisposable

...

@code {
    public void Dispose()
    {
        ...
    }
}

Jeśli obiekt wymaga usunięcia, można użyć wyrażenia lambda do usuwania obiektu, gdy IDisposable.Dispose jest wywoływana:If an object requires disposal, a lambda can be used to dispose of the object when IDisposable.Dispose is called:

Pages/CounterWithTimerDisposal.razor:Pages/CounterWithTimerDisposal.razor:

@page "/counter-with-timer-disposal"
@using System.Timers
@implements IDisposable

<h1>Counter with <code>Timer</code> disposal</h1>

<p>Current count: @currentCount</p>

@code {
    private int currentCount = 0;
    private Timer timer = new Timer(1000);

    protected override void OnInitialized()
    {
        timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
        timer.Start();
    }

    private void OnTimerCallback()
    {
        _ = InvokeAsync(() =>
        {
            currentCount++;
            StateHasChanged();
        });
    }

    public void IDisposable.Dispose() => timer.Dispose();
}

Poprzedni przykład jest wyświetlany w BlazorRenderowanie składników ASP.NET Core .The preceding example appears in BlazorRenderowanie składników ASP.NET Core.

W przypadku asynchronicznych zadań usuwania Użyj DisposeAsync zamiast Dispose() :For asynchronous disposal tasks, use DisposeAsync instead of Dispose():

public async ValueTask DisposeAsync()
{
    ...
}

Uwaga

Wywoływanie metody StateHasChanged Dispose nie jest obsługiwane.Calling StateHasChanged in Dispose isn't supported. StateHasChanged może być wywoływana w ramach rozrywania modułu renderowania, dlatego żądanie aktualizacji interfejsu użytkownika nie jest obsługiwane.StateHasChanged might be invoked as part of tearing down the renderer, so requesting UI updates at that point isn't supported.

Procedury obsługi zdarzeń anulowania subskrypcji z zdarzeń platformy .NET.Unsubscribe event handlers from .NET events. Poniższe przykłady Blazor formularzy pokazują, jak anulować subskrypcję programu obsługi zdarzeń w Dispose metodzie:The following Blazor form examples show how to unsubscribe an event handler in the Dispose method:

  • Pole prywatne i podejście lambdaPrivate field and lambda approach

    @implements IDisposable
    
    <EditForm EditContext="@editContext">
    
        ...
    
        <button type="submit" disabled="@formInvalid">Submit</button>
    </EditForm>
    
    @code {
        ...
        private EventHandler<FieldChangedEventArgs> fieldChanged;
    
        protected override void OnInitialized()
        {
            editContext = new EditContext(...);
    
            fieldChanged = (_, __) =>
            {
                ...
            };
    
            editContext.OnFieldChanged += fieldChanged;
        }
    
        public void Dispose()
        {
            editContext.OnFieldChanged -= fieldChanged;
        }
    }
    
  • Podejście metody prywatnejPrivate method approach

    @implements IDisposable
    
    <EditForm EditContext="@editContext">
    
        ...
    
        <button type="submit" disabled="@formInvalid">Submit</button>
    </EditForm>
    
    @code {
        ...
    
        protected override void OnInitialized()
        {
            editContext = new EditContext(...);
            editContext.OnFieldChanged += HandleFieldChanged;
        }
    
        private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
        {
            ...
        }
    
        public void Dispose()
        {
            editContext.OnFieldChanged -= HandleFieldChanged;
        }
    }
    

Gdy są używane anonimowe funkcje, metody lub wyrażenia, nie trzeba implementować IDisposable i anulować subskrybowania delegatów.When anonymous functions, methods or expressions, are used, it isn't necessary to implement IDisposable and unsubscribe delegates. Niepowodzenie anulowania subskrypcji delegata jest jednak problemem, gdy obiekt ujawniający zdarzenie wyrejestruje okres istnienia elementu delegowanego.However, failing to unsubscribe a delegate is a problem when the object exposing the event outlives the lifetime of the component registering the delegate. W takim przypadku przyczyną przecieku pamięci jest fakt, że zarejestrowany delegat zachowuje oryginalny obiekt.When this occurs, a memory leak results because the registered delegate keeps the original object alive. W związku z tym należy stosować następujące podejścia tylko wtedy, gdy wiadomo, że delegat zdarzenia szybko usuwa.Therefore, only use the following approaches when you know that the event delegate disposes quickly. W razie wątpliwości dotyczących okresu istnienia obiektów, które wymagają usunięcia, zasubskrybuj metodę delegata i prawidłowo Usuń delegata, jak pokazano w poprzednich przykładach.When in doubt about the lifetime of objects that require disposal, subscribe a delegate method and properly dispose the delegate as the preceding examples show.

  • Anonimowe podejście metody lambda (jawne usuwanie nie jest wymagane)Anonymous lambda method approach (explicit disposal not required)

    private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
    {
        formInvalid = !editContext.Validate();
        StateHasChanged();
    }
    
    protected override void OnInitialized()
    {
        editContext = new EditContext(starship);
        editContext.OnFieldChanged += (s, e) => HandleFieldChanged((editContext)s, e);
    }
    
  • Anonimowe podejście wyrażenia lambda (jawne usuwanie nie jest wymagane)Anonymous lambda expression approach (explicit disposal not required)

    private ValidationMessageStore messageStore;
    
    [CascadingParameter]
    private EditContext CurrentEditContext { get; set; }
    
    protected override void OnInitialized()
    {
        ...
    
        messageStore = new ValidationMessageStore(CurrentEditContext);
    
        CurrentEditContext.OnValidationRequested += (s, e) => messageStore.Clear();
        CurrentEditContext.OnFieldChanged += (s, e) => 
            messageStore.Clear(e.FieldIdentifier);
    }
    

    Pełny przykład powyższego kodu z anonimowymi wyrażeniami lambda pojawia się w ASP.NET Core Blazor formularzy i walidacji .The full example of the preceding code with anonymous lambda expressions appears in ASP.NET Core Blazor formularzy i walidacji.

Aby uzyskać więcej informacji, zobacz Oczyszczanie zasobów niezarządzanych i tematy, które po nich wykonują, przy wdrażaniu Dispose DisposeAsync metod i.For more information, see Cleaning up unmanaged resources and the topics that follow it on implementing the Dispose and DisposeAsync methods.

Anulowanie pracy w tleCancelable background work

Składniki często wykonują długotrwałą pracę w tle, taką jak tworzenie wywołań sieciowych ( HttpClient ) i współdziałanie z bazami danych.Components often perform long-running background work, such as making network calls (HttpClient) and interacting with databases. Pożądane jest zatrzymanie pracy w tle w celu zapełnienia zasobów systemowych w kilku sytuacjach.It's desirable to stop the background work to conserve system resources in several situations. Na przykład operacje asynchroniczne w tle nie są automatycznie przerywane, gdy użytkownik przechodzi poza składnik.For example, background asynchronous operations don't automatically stop when a user navigates away from a component.

Inne powody, dla których elementy robocze w tle mogą wymagać anulowania, to:Other reasons why background work items might require cancellation include:

  • Rozpoczęto wykonywanie zadania w tle z uszkodzonymi danymi wejściowymi lub przetwarzaniem parametrów.An executing background task was started with faulty input data or processing parameters.
  • Bieżący zestaw wykonywanych elementów roboczych w tle musi zostać zastąpiony nowym zestawem elementów roboczych.The current set of executing background work items must be replaced with a new set of work items.
  • Priorytet aktualnie wykonywanych zadań musi zostać zmieniony.The priority of currently executing tasks must be changed.
  • Aby można było ponownie wdrożyć je na serwerze, należy zamknąć aplikację.The app has to be shut down in order to redeploy it to the server.
  • Zasoby serwera są ograniczone, co wymaga ponownego zaplanowania elementów roboczych w tle.Server resources become limited, necessitating the rescheduling of background work items.

Aby zaimplementować w składniku wzorzec pracy z możliwością anulowania w tle:To implement a cancelable background work pattern in a component:

W poniższym przykładzie:In the following example:

  • await Task.Delay(5000, cts.Token); reprezentuje długotrwałe działanie asynchroniczne w tle.await Task.Delay(5000, cts.Token); represents long-running asynchronous background work.
  • BackgroundResourceMethod reprezentuje długotrwałą metodę w tle, która nie powinna być uruchamiana, jeśli element Resource zostanie usunięty przed wywołaniem metody.BackgroundResourceMethod represents a long-running background method that shouldn't start if the Resource is disposed before the method is called.
@implements IDisposable
@using System.Threading

<button @onclick="LongRunningWork">Trigger long running work</button>

@code {
    private Resource resource = new Resource();
    private CancellationTokenSource cts = new CancellationTokenSource();

    protected async Task LongRunningWork()
    {
        await Task.Delay(5000, cts.Token);

        cts.Token.ThrowIfCancellationRequested();
        resource.BackgroundResourceMethod();
    }

    public void Dispose()
    {
        cts.Cancel();
        cts.Dispose();
        resource.Dispose();
    }

    private class Resource : IDisposable
    {
        private bool disposed;

        public void BackgroundResourceMethod()
        {
            if (disposed)
            {
                throw new ObjectDisposedException(nameof(Resource));
            }
            
            ...
        }
        
        public void Dispose()
        {
            disposed = true;
        }
    }
}

Blazor Server zdarzenia ponownego połączeniaBlazor Server reconnection events

Zdarzenia cyklu życia składnika omówione w tym artykule działają niezależnie od Blazor Server programów obsługi zdarzeń ponownego połączenia.The component lifecycle events covered in this article operate separately from Blazor Server's reconnection event handlers. Gdy Blazor Server aplikacja utraci SignalR połączenie z klientem, wszystkie aktualizacje interfejsu użytkownika są przerywane.When a Blazor Server app loses its SignalR connection to the client, only UI updates are interrupted. Aktualizacje interfejsu użytkownika są wznawiane po ponownym nawiązaniu połączenia.UI updates are resumed when the connection is re-established. Aby uzyskać więcej informacji na temat zdarzeń i konfiguracji obsługi obwodów, zobacz Blazor SignalR Wskazówki dotyczące ASP.NET Core .For more information on circuit handler events and configuration, see Blazor SignalR Wskazówki dotyczące ASP.NET Core.