Skip to content

Commit e8ac31d

Browse files
authored
Add JS interop example (#26817)
1 parent 874df6f commit e8ac31d

File tree

1 file changed

+75
-13
lines changed

1 file changed

+75
-13
lines changed

aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,9 +1893,9 @@ A helper class can invoke a .NET instance method as an <xref:System.Action>. Hel
18931893

18941894
In the following example:
18951895

1896-
* The `CallDotNetExample6` component contains several `ListItem` components, which is a shared component in the app's `Shared` folder.
1897-
* Each `ListItem` component is composed of a message and a button.
1898-
* When a `ListItem` component button is selected, that `ListItem`'s `UpdateMessage` method changes the list item text and hides the button.
1896+
* The `CallDotNetExample6` component contains several `ListItem1` components, which is a shared component in the app's `Shared` folder.
1897+
* Each `ListItem1` component is composed of a message and a button.
1898+
* When a `ListItem1` component button is selected, that `ListItem1`'s `UpdateMessage` method changes the list item text and hides the button.
18991899

19001900
The following `MessageUpdateInvokeHelper` class maintains a JS-invokable .NET method, `UpdateMessageCaller`, to invoke the <xref:System.Action> specified when the class is instantiated. `BlazorSample` is the app's assembly name.
19011901

@@ -1918,29 +1918,91 @@ The following `updateMessageCaller` JS function invokes the `UpdateMessageCaller
19181918

19191919
In the preceding example, the variable name `dotNetHelper` is arbitrary and can be changed to any preferred name.
19201920

1921-
The following `ListItem` component is a shared component that can be used any number of times in a parent component and creates list items (`<li>...</li>`) for an HTML list (`<ul>...</ul>` or `<ol>...</ol>`). Each `ListItem` component instance establishes an instance of `MessageUpdateInvokeHelper` with an <xref:System.Action> set to its `UpdateMessage` method.
1921+
The following `ListItem1` component is a shared component that can be used any number of times in a parent component and creates list items (`<li>...</li>`) for an HTML list (`<ul>...</ul>` or `<ol>...</ol>`). Each `ListItem1` component instance establishes an instance of `MessageUpdateInvokeHelper` with an <xref:System.Action> set to its `UpdateMessage` method.
19221922

1923-
When a `ListItem` component's **`InteropCall`** button is selected, `updateMessageCaller` is invoked with a created <xref:Microsoft.JSInterop.DotNetObjectReference> for the `MessageUpdateInvokeHelper` instance. This permits the framework to call `UpdateMessageCaller` on that `ListItem`'s `MessageUpdateInvokeHelper` instance. The passed <xref:Microsoft.JSInterop.DotNetObjectReference> is disposed in JS (`dotNetHelper.dispose()`).
1923+
When a `ListItem1` component's **`InteropCall`** button is selected, `updateMessageCaller` is invoked with a created <xref:Microsoft.JSInterop.DotNetObjectReference> for the `MessageUpdateInvokeHelper` instance. This permits the framework to call `UpdateMessageCaller` on that `ListItem1`'s `MessageUpdateInvokeHelper` instance. The passed <xref:Microsoft.JSInterop.DotNetObjectReference> is disposed in JS (`dotNetHelper.dispose()`).
19241924

1925-
`Shared/ListItem.razor`:
1925+
`Shared/ListItem1.razor`:
19261926

1927-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Shared/call-dotnet-from-js/ListItem.razor":::
1927+
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Shared/call-dotnet-from-js/ListItem1.razor":::
19281928

19291929
[`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged) is called to update the UI when `message` is set in `UpdateMessage`. If `StateHasChanged` isn't called, Blazor has no way of knowing that the UI should be updated when the <xref:System.Action> is invoked.
19301930

1931-
The following `CallDotNetExample6` parent component includes four list items, each an instance of the `ListItem` component.
1931+
The following `CallDotNetExample6` parent component includes four list items, each an instance of the `ListItem1` component.
19321932

19331933
`Pages/CallDotNetExample6.razor`:
19341934

19351935
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/call-dotnet-from-js/CallDotNetExample6.razor" highlight="6-9":::
19361936

19371937
The following image shows the rendered `CallDotNetExample6` parent component after the second **`InteropCall`** button is selected:
19381938

1939-
* The second `ListItem` component has displayed the `UpdateMessage Called!` message.
1940-
* The **`InteropCall`** button for the second `ListItem` component isn't visible because the button's CSS `display` property is set to `none`.
1939+
* The second `ListItem1` component has displayed the `UpdateMessage Called!` message.
1940+
* The **`InteropCall`** button for the second `ListItem1` component isn't visible because the button's CSS `display` property is set to `none`.
19411941

19421942
![Rendered 'CallDotNetExample6' component example](~/blazor/javascript-interoperability/call-dotnet-from-javascript/_static/component-example-6.png)
19431943

1944+
## Component instance .NET method called from `DotNetObjectReference` assigned to an element property
1945+
1946+
The assignment of a <xref:Microsoft.JSInterop.DotNetObjectReference> to a property of an HTML element permits calling .NET methods on a component instance:
1947+
1948+
* An [element reference](xref:blazor/js-interop/call-javascript-from-dotnet#capture-references-to-elements) is captured (<xref:Microsoft.AspNetCore.Components.ElementReference>).
1949+
* In the component's [`OnAfterRender{Async}` method](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync), a JavaScript (JS) function is invoked with the element reference and the component instance as a <xref:Microsoft.JSInterop.DotNetObjectReference>. The JS function attaches the <xref:Microsoft.JSInterop.DotNetObjectReference> to the element in a property.
1950+
* When an element event is invoked in JS (for example, `onclick`), the element's attached <xref:Microsoft.JSInterop.DotNetObjectReference> is used to call a .NET method.
1951+
1952+
Similar to the approach described in the [Component instance .NET method helper class](#component-instance-net-method-helper-class) section, this approach is useful in the following scenarios:
1953+
1954+
* When several components of the same type are rendered on the same page.
1955+
* In Blazor Server apps with multiple users concurrently using the same component.
1956+
* The .NET method is invoked from a JS event (for example, `onclick`), not from a Blazor event (for example, `@onclick`).
1957+
1958+
In the following example:
1959+
1960+
* The `CallDotNetExample7` component contains several `ListItem2` components, which is a shared component in the app's `Shared` folder.
1961+
* Each `ListItem2` component is composed of a list item message `<span>` and a second `<span>` with a `display` CSS property set to `inline-block` for display.
1962+
* When a `ListItem2` component list item is selected, that `ListItem2`'s `UpdateMessage` method changes the list item text in the first `<span>` and hides the second `<span>` by setting its `display` property to `none`.
1963+
1964+
The following `assignDotNetHelper` JS function assigns the <xref:Microsoft.JSInterop.DotNetObjectReference> to an element in a property named `dotNetHelper`:
1965+
1966+
```html
1967+
<script>
1968+
window.assignDotNetHelper = (element, dotNetHelper) => {
1969+
element.dotNetHelper = dotNetHelper;
1970+
}
1971+
</script>
1972+
```
1973+
1974+
The following `interopCall` JS function uses the <xref:Microsoft.JSInterop.DotNetObjectReference> for the passed element to invoke a .NET method named `UpdateMessage`:
1975+
1976+
```html
1977+
<script>
1978+
window.interopCall = async (element) => {
1979+
await element.dotNetHelper.invokeMethodAsync('UpdateMessage');
1980+
}
1981+
</script>
1982+
```
1983+
1984+
[!INCLUDE[](~/blazor/includes/js-location.md)]
1985+
1986+
In the preceding example, the variable name `dotNetHelper` is arbitrary and can be changed to any preferred name.
1987+
1988+
The following `ListItem2` component is a shared component that can be used any number of times in a parent component and creates list items (`<li>...</li>`) for an HTML list (`<ul>...</ul>` or `<ol>...</ol>`).
1989+
1990+
Each `ListItem2` component instance invokes the `assignDotNetHelper` JS function in [`OnAfterRenderAsync`](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync) with an element reference (the first `<span>` element of the list item) and the component instance as a <xref:Microsoft.JSInterop.DotNetObjectReference>.
1991+
1992+
When a `ListItem2` component's message `<span>` is selected, `interopCall` is invoked passing the `<span>` element as a parameter (`this`), which invokes the `UpdateMessage` .NET method. In `UpdateMessage`, [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged) is called to update the UI when `message` is set and the `display` property of the second `<span>` is updated. If `StateHasChanged` isn't called, Blazor has no way of knowing that the UI should be updated when the method is invoked.
1993+
1994+
The <xref:Microsoft.JSInterop.DotNetObjectReference> is disposed when the component is disposed.
1995+
1996+
`Shared/ListItem2.razor`:
1997+
1998+
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Shared/call-dotnet-from-js/ListItem2.razor":::
1999+
2000+
The following `CallDotNetExample7` parent component includes four list items, each an instance of the `ListItem2` component.
2001+
2002+
`Pages/CallDotNetExample7.razor`:
2003+
2004+
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/call-dotnet-from-js/CallDotNetExample7.razor" highlight="6-9":::
2005+
19442006
## Synchronous JS interop in Blazor WebAssembly apps
19452007

19462008
[!INCLUDE[](~/blazor/includes/js-interop/synchronous-js-interop-call-dotnet.md)]
@@ -2000,13 +2062,13 @@ Provide a `sendByteArray` JS function. The function is called by a button in the
20002062

20012063
[!INCLUDE[](~/blazor/includes/js-location.md)]
20022064

2003-
`Pages/CallDotNetExample7.razor`:
2065+
`Pages/CallDotNetExample8.razor`:
20042066

20052067
```razor
2006-
@page "/call-dotnet-example-7"
2068+
@page "/call-dotnet-example-8"
20072069
@using System.Text
20082070
2009-
<h1>Call .NET Example 7</h1>
2071+
<h1>Call .NET Example 8</h1>
20102072
20112073
<p>
20122074
<button onclick="sendByteArray()">Send Bytes</button>

0 commit comments

Comments
 (0)