Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-link API #31155

Merged
merged 2 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ The following `Daleks` component displays the cascaded values.
}
```

In the following example, `Daleks` is registered as a cascading value using `CascadingValueSource<T>`, where `<T>` is the type. The `isFixed` flag indicates whether the value is fixed. If false, all receipients are subscribed for update notifications, which are issued by calling `NotifyChangedAsync`. Subscriptions create overhead and reduce performance, so set `isFixed` to `true` if the value doesn't change.
In the following example, `Daleks` is registered as a cascading value using [`CascadingValueSource<T>`](xref:Microsoft.AspNetCore.Components.CascadingValueSource%601), where `<T>` is the type. The `isFixed` flag indicates whether the value is fixed. If false, all recipients are subscribed for update notifications, which are issued by calling <xref:Microsoft.AspNetCore.Components.CascadingValueSource%601.NotifyChangedAsync%2A>. Subscriptions create overhead and reduce performance, so set `isFixed` to `true` if the value doesn't change.

```csharp
builder.Services.AddCascadingValue(sp =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@ To choose among these approaches, reusable Razor component authors must make a c

## When to use the `@rendermode` directive

In most cases, reusable component authors should **not** specify a render mode, even when interactivity is required. This is because the component author doesn't know whether the app enables support for `InteractiveServer`, `InteractiveWebAssembly`, or both with `InteractiveAuto`. By not specifying a `@rendermode`, the component author leaves the choice to the app developer.
In most cases, reusable component authors should **not** specify a render mode, even when interactivity is required. This is because the component author doesn't know whether the app enables support for <xref:Microsoft.AspNetCore.Components.Web.RenderMode.InteractiveServer>, <xref:Microsoft.AspNetCore.Components.Web.RenderMode.InteractiveWebAssembly>, or both with <xref:Microsoft.AspNetCore.Components.Web.RenderMode.InteractiveAuto>. By not specifying a `@rendermode`, the component author leaves the choice to the app developer.

Even if the component author thinks that interactivity is required, there may still be cases where an app author considers it sufficient to use static SSR alone. For example, a draggable, zoomable map component may seem to require interactivity. However, some scenarios may only call for rendering a static map image and avoiding drag/zoom features.

The only reason why a reusable component author should use the `@rendermode` directive on their component is if the implementation is fundamentally coupled to one specific render mode and would certainly cause an error if used in a different mode. Consider a component with a core purpose of interacting directly with the host OS using Windows or Linux-specific APIs. It might be impossible to use such a component on WebAssembly. If so, it's reasonable to declare `@rendermode InteractiveServer` for the component.

## Streaming rendering

Reusable Razor components are free to declare `@attribute [StreamRendering]` for [streaming rendering](xref:blazor/components/rendering#streaming-rendering). This results in incremental UI updates during static SSR. Since the same data-loading patterns produce incremental UI updates during interactive rendering (regardless of the [`StreamRendering` attribute](xref:Microsoft.AspNetCore.Components.StreamRenderingAttribute)), the component can behave correctly in all cases. Even in cases where streaming static SSR is suppressed on the server, the component still renders its correct final state.
Reusable Razor components are free to declare `@attribute [StreamRendering]` for [streaming rendering](xref:blazor/components/rendering#streaming-rendering) ([`[StreamRendering]` attribute API](xref:Microsoft.AspNetCore.Components.StreamRenderingAttribute)). This results in incremental UI updates during static SSR. Since the same data-loading patterns produce incremental UI updates during interactive rendering, regardless of the presence of the `[StreamRendering]` attribute, the component can behave correctly in all cases. Even in cases where streaming static SSR is suppressed on the server, the component still renders its correct final state.

## Using links across render modes

Reusable Razor components may use links and enhanced navigation. HTML `<a>` tags should produce equivalent behaviors with or without an interactive `<Router>` component and whether or not enhanced navigation is enabled/disabled at an ancestor level in the DOM.
Reusable Razor components may use links and enhanced navigation. HTML `<a>` tags should produce equivalent behaviors with or without an interactive <xref:Microsoft.AspNetCore.Components.Routing.Router> component and whether or not enhanced navigation is enabled/disabled at an ancestor level in the DOM.

## Using forms across render modes

Expand Down Expand Up @@ -119,7 +119,7 @@ Consider the following example:
}
```

The `Enhance`, `FormName`, and `SupplyParameterFromForm` APIs are only used during static SSR and are ignored during interactive rendering. The form works correctly during both interactive and static SSR.
The <xref:Microsoft.AspNetCore.Components.Forms.EditForm.Enhance%2A>, <xref:Microsoft.AspNetCore.Components.Forms.EditForm.FormName%2A>, and <xref:Microsoft.AspNetCore.Components.SupplyParameterFromFormAttribute> APIs are only used during static SSR and are ignored during interactive rendering. The form works correctly during both interactive and static SSR.

## Avoid APIs that are specific to static SSR

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/components/class-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ To provide `Component1`'s `my-component` CSS class, link to the library's styles

## Make routable components available from the RCL

To make routable components in the RCL available for direct requests, the RCL's assembly must be added to the app's router.
To make routable components in the RCL available for direct requests, the RCL's assembly must be disclosed to the app's router.

Open the app's `App` component (`App.razor`). Add or update the `AdditionalAssemblies` parameter of the `<Router>` tag to include the RCL's assembly. In the following example, the `ComponentLibrary.Component1` component is used to discover the RCL's assembly.

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/components/data-binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ The most plausible `null` equivalent in HTML is an *empty string* `value`. The B

## Unparsable values

When a user provides an unparsable value to a databound element, the unparsable value is automatically reverted to its previous value when the bind event is triggered.
When a user provides an unparsable value to a data-bound element, the unparsable value is automatically reverted to its previous value when the bind event is triggered.

Consider the following component, where an `<input>` element is bound to an `int` type with an initial value of `123`.

Expand Down
6 changes: 3 additions & 3 deletions aspnetcore/blazor/components/event-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public class CustomEventArgs : EventArgs
}
```

Wire up the custom event with the event arguments by adding an <xref:Microsoft.AspNetCore.Components.EventHandlerAttribute> attribute annotation for the custom event:
Wire up the custom event with the event arguments by adding an [`[EventHandler]` attribute](xref:Microsoft.AspNetCore.Components.EventHandlerAttribute) annotation for the custom event:

* In order for the compiler to find the `[EventHandler]` class, it must be placed into a C# class file (`.cs`), making it a normal top-level class.
* Mark the class `public`.
Expand Down Expand Up @@ -255,7 +255,7 @@ If the `@oncustomevent` attribute isn't recognized by [IntelliSense](/visualstud

Whenever the custom event is fired on the DOM, the event handler is called with the data passed from the JavaScript.

If you're attempting to fire a custom event, [`bubbles`](https://developer.mozilla.org/docs/Web/API/Event/bubbles) must be enabled by setting its value to `true`. Otherwise, the event doesn't reach the Blazor handler for processing into the C# custom <xref:Microsoft.AspNetCore.Components.EventHandlerAttribute> method. For more information, see [MDN Web Docs: Event bubbling](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events#event_bubbling).
If you're attempting to fire a custom event, [`bubbles`](https://developer.mozilla.org/docs/Web/API/Event/bubbles) must be enabled by setting its value to `true`. Otherwise, the event doesn't reach the Blazor handler for processing into the C# custom [`[EventHandler]` attribute](xref:Microsoft.AspNetCore.Components.EventHandlerAttribute) class. For more information, see [MDN Web Docs: Event bubbling](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events#event_bubbling).

### Custom clipboard paste event example

Expand Down Expand Up @@ -459,7 +459,7 @@ Alternatively, use a `foreach` loop with <xref:System.Linq.Enumerable.Range%2A?d

A common scenario with nested components executes a parent component's method when a child component event occurs. An `onclick` event occurring in the child component is a common use case. To expose events across components, use an <xref:Microsoft.AspNetCore.Components.EventCallback>. A parent component can assign a callback method to a child component's <xref:Microsoft.AspNetCore.Components.EventCallback>.

The following `Child` component demonstrates how a button's `onclick` handler is set up to receive an <xref:Microsoft.AspNetCore.Components.EventCallback> delegate from the sample's `ParentComponent`. The <xref:Microsoft.AspNetCore.Components.EventCallback> is typed with `MouseEventArgs`, which is appropriate for an `onclick` event from a peripheral device.
The following `Child` component demonstrates how a button's `onclick` handler is set up to receive an <xref:Microsoft.AspNetCore.Components.EventCallback> delegate from the sample's `ParentComponent`. The <xref:Microsoft.AspNetCore.Components.EventCallback> is typed with <xref:Microsoft.AspNetCore.Components.Web.MouseEventArgs>, which is appropriate for an `onclick` event from a peripheral device.

`Child.razor`:

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/components/generic-type-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ By adding `@attribute [CascadingTypeParameter(...)]` to a component, the specifi
* Also declare a [`@typeparam`](xref:mvc/views/razor#typeparam) with the exact same name.
* Don't have another value explicitly supplied or implicitly inferred for the type parameter. If another value is supplied or inferred, it takes precedence over the cascaded generic type.

When receiving a cascaded type parameter, components obtain the parameter value from the closest ancestor that has a <xref:Microsoft.AspNetCore.Components.CascadingTypeParameterAttribute> with a matching name. Cascaded generic type parameters are overridden within a particular subtree.
When receiving a cascaded type parameter, components obtain the parameter value from the closest ancestor that has a [`[CascadingTypeParameter]` attribute](xref:Microsoft.AspNetCore.Components.CascadingTypeParameterAttribute) with a matching name. Cascaded generic type parameters are overridden within a particular subtree.

Matching is only performed by name. Therefore, we recommend avoiding a cascaded generic type parameter with a generic name, for example `T` or `TItem`. If a developer opts into cascading a type parameter, they're implicitly promising that its name is unique enough not to clash with other cascaded type parameters from unrelated components.

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/components/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ Quote &copy;2005 [Universal Pictures](https://www.uphe.com): [Serenity](https://

## Route parameters

Components can specify route parameters in the route template of the [`@page`][9] directive. The [Blazor router](xref:blazor/fundamentals/routing) uses route parameters to populate corresponding component parameters.
Components can specify route parameters in the route template of the [`@page`][9] directive. The [Blazor Router](xref:blazor/fundamentals/routing) uses route parameters to populate corresponding component parameters.

:::moniker range=">= aspnetcore-5.0"

Expand Down
Loading