Skip to content

Commit 4324c05

Browse files
authored
@bind:get/:set clarifications (#36496)
1 parent 45cbae6 commit 4324c05

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

aspnetcore/blazor/components/data-binding.md

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,38 @@ Additional examples
221221

222222
For more information on the `InputText` component, see <xref:blazor/forms/input-components>.
223223

224-
Components support two-way data binding by defining a pair of `@bind` attributes with either a `:get` or `:set` modifier . The `{PARAMETER}` placeholder in the following examples is used to bind a component parameter:
224+
Components support two-way data binding by defining a pair of `@bind` attributes with either a `:get` or `:set` modifier. The `{PARAMETER}` placeholder in the following examples is used to bind a component parameter:
225225

226226
* `@bind:get`/`@bind-{PARAMETER}:get`: Specifies the value to bind.
227227
* `@bind:set`/`@bind-{PARAMETER}:set`: Specifies a callback for when the value changes.
228228

229-
The `:get` and `:set` modifiers are always used together.
229+
The `:get`/`:set` modifiers are always used together.
230230

231-
With `:get`/`:set` binding, you can react to a value change before it's applied to the DOM, and you can change the applied value, if necessary. Whereas with `@bind:event="{EVENT}"` attribute binding, where the `{EVENT}` placeholder is a DOM event, you receive the notification after the DOM is updated, and there's no capacity to modify the applied value while binding.
231+
For binding to HTML elements, use `:get`/`:set` modifiers to ensure an `<input>` element stays synchronized with a bound value, even when the value is modified in the handler:
232232

233-
The following `BindGetSet` component demonstrates `@bind:get`/`@bind:set` syntax for `<input>` elements and the [`InputText` component](xref:blazor/forms/input-components) used by [Blazor forms](xref:blazor/forms/index) in synchronous (`Set`) and asynchronous (`SetAsync`) scenarios.
233+
```razor
234+
<input @bind:get="inputValue" @bind:set="HandleValueChange" />
235+
```
236+
237+
> [!NOTE]
238+
> The legacy approach prior to the release of .NET 7 used the `value` attribute with `@onchange`:
239+
>
240+
> ```razor
241+
> <input value="@inputValue" @onchange="HandleValueChange" />
242+
> ```
243+
>
244+
> The preceding approach can cause synchronization errors, where the `<input>` element displays a different value than the value held in the bound variable. Migrate to `:get`/`:set` modifiers to avoid this issue.
245+
246+
For component parameters, the following syntaxes for a hypothetical `Child` component are functionally equivalent:
247+
248+
```razor
249+
<Child Value="@inputValue" ValueChanged="@(v => inputValue = v)" />
250+
<Child @bind-Value:get="inputValue" @bind-Value:set="@(v => inputValue = v)" />
251+
```
252+
253+
With `:get`/`:set` modifier binding, you can react to a value change before it's applied to the DOM, and you can change the applied value, if necessary. Whereas with `@bind:event="{EVENT}"` attribute binding, where the `{EVENT}` placeholder is a DOM event, you receive the notification after the DOM is updated, and there's no capacity to modify the applied value while binding.
254+
255+
The following `BindGetSet` component demonstrates `:get`/`:set` syntax for `<input>` elements and the [`InputText` component](xref:blazor/forms/input-components) used by [Blazor forms](xref:blazor/forms/index) in synchronous (`Set`) and asynchronous (`SetAsync`) scenarios.
234256

235257
`BindGetSet.razor`:
236258

@@ -270,7 +292,7 @@ The following `BindGetSet` component demonstrates `@bind:get`/`@bind:set` syntax
270292

271293
For more information on the `InputText` component, see <xref:blazor/forms/input-components>.
272294

273-
For another example use of `@bind:get` and `@bind:set`, see the [Bind across more than two components](#bind-across-more-than-two-components) section later in this article.
295+
For another example use of `:get` and `:set` modifiers, see the [Bind across more than two components](#bind-across-more-than-two-components) section later in this article.
274296

275297
Razor attribute binding is case-sensitive:
276298

@@ -279,7 +301,7 @@ Razor attribute binding is case-sensitive:
279301

280302
## Use `@bind:get`/`@bind:set` modifiers and avoid event handlers for two-way data binding
281303

282-
Two-way data binding isn't possible to implement with an event handler. Use `@bind:get`/`@bind:set` modifiers for two-way data binding.
304+
Two-way data binding isn't possible to implement with an event handler. Use `:get`/`:set` modifiers for two-way data binding.
283305

284306
<span aria-hidden="true">❌</span> Consider the following ***dysfunctional approach*** for two-way data binding using an event handler:
285307

@@ -306,9 +328,9 @@ Two-way data binding isn't possible to implement with an event handler. Use `@bi
306328

307329
The `OnInput` event handler updates the value of `inputValue` to `Long!` after a fourth character is provided. However, the user can continue adding characters to the element value in the UI. The value of `inputValue` isn't bound back to the element's value with each keystroke. The preceding example is only capable of one-way data binding.
308330

309-
The reason for this behavior is that Blazor isn't aware that your code intends to modify the value of `inputValue` in the event handler. Blazor doesn't try to force DOM element values and .NET variable values to match unless they're bound with `@bind` syntax. In earlier versions of Blazor, two-way data binding is implemented by [binding the element to a property and controlling the property's value with its setter](#binding-to-a-property-with-c-get-and-set-accessors). In ASP.NET Core in .NET 7 or later, `@bind:get`/`@bind:set` modifier syntax is used to implement two-way data binding, as the next example demonstrates.
331+
The reason for this behavior is that Blazor isn't aware that your code intends to modify the value of `inputValue` in the event handler. Blazor doesn't try to force DOM element values and .NET variable values to match unless they're bound with `@bind` syntax. In earlier versions of Blazor, two-way data binding is implemented by [binding the element to a property and controlling the property's value with its setter](#binding-to-a-property-with-c-get-and-set-accessors). In ASP.NET Core in .NET 7 or later, `:get`/`:set` modifier syntax is used to implement two-way data binding, as the next example demonstrates.
310332

311-
<span aria-hidden="true">✔️</span> Consider the following ***correct approach*** using `@bind:get`/`@bind:set` for two-way data binding:
333+
<span aria-hidden="true">✔️</span> Consider the following ***correct approach*** using `:get`/`:set` for two-way data binding:
312334

313335
```razor
314336
<p>
@@ -331,7 +353,7 @@ The reason for this behavior is that Blazor isn't aware that your code intends t
331353
}
332354
```
333355

334-
Using `@bind:get`/`@bind:set` modifiers both controls the underlying value of `inputValue` via `@bind:set` and binds the value of `inputValue` to the element's value via `@bind:get`. The preceding example demonstrates the correct approach for implementing two-way data binding.
356+
Using `:get`/`:set` modifiers both controls the underlying value of `inputValue` via `:set` and binds the value of `inputValue` to the element's value via `:get`. The preceding example demonstrates the correct approach for implementing two-way data binding.
335357

336358
:::moniker-end
337359

0 commit comments

Comments
 (0)