What Changed
In v23.2 and earlier, data is reinitialized on every component re-render when you use the DataAsync
property to bind the ComboBox/TagBox to data. For example, when you use the DataAsync
property in cascading components:
Razor<DxComboBox Data="FirstDataSource"
ValueFieldName="@nameof(MyModel.ID)"
TextFieldName="@nameof(MyModel.Name)"
@bind-Value="@FirstValue" />
<DxComboBox DataAsync="(cancellationToken) => LoadDataAsync(FirstValue, cancellationToken)"
ValueFieldName="@nameof(MyModel.ID)"
TextFieldName="@nameof(MyModel.Name)"
@bind-Value="@SecondValue" />
@code {
IEnumerable<MyModel> FirstDataSource { get; set; }
int? FirstValue { get; set; }
string? SecondValue { get; set; }
public class MyModel {
public int ID { get; set; }
public string Name { get; set; }
}
protected override void OnInitialized() {
FirstDataSource = Enumerable.Range(0, 10).Select(i => new MyModel() { ID = i, Name = $"Name {i}" });
}
public async Task<IEnumerable<string>> LoadDataAsync(int? value, CancellationToken cancellationToken = default(CancellationToken)) {
if(!value.HasValue)
return Enumerable.Empty<string>();
return FirstDataSource.Where(i => i.ID % value == 0).Select(i => i.Name);
}
}
In v24.1, ComboBox/TagBox does not fetch data on re-render. If you need to force the component to fetch data, use one of the following approaches:
- Set a key and update it when you need to update data
Razor<DxComboBox Data="FirstDataSource"
ValueFieldName="@nameof(MyModel.ID)"
TextFieldName="@nameof(MyModel.Name)"
Value="@FirstValue"
ValueChanged="@((int? value) => { FirstValue = value; keyValue++;})" />
<DxComboBox @key=@keyValue
DataAsync="(cancellationToken) => LoadDataAsync(FirstValue, cancellationToken)"
ValueFieldName="@nameof(MyModel.ID)"
TextFieldName="@nameof(MyModel.Name)"
@bind-Value="@SecondValue" />
@code {
int keyValue;
IEnumerable<MyModel> FirstDataSource { get; set; }
int? FirstValue { get; set; }
string? SecondValue { get; set; }
public class MyModel {
public int ID { get; set; }
public string Name { get; set; }
}
protected override void OnInitialized() {
FirstDataSource = Enumerable.Range(0, 10).Select(i => new MyModel() { ID = i, Name = $"Name {i}" });
}
public async Task<IEnumerable<string>> LoadDataAsync(int? value, CancellationToken cancellationToken = default(CancellationToken)) {
if(!value.HasValue)
return Enumerable.Empty<string>();
return FirstDataSource.Where(i => i.ID % value == 0).Select(i => i.Name);
}
}
- Use the
Data
property instead of theDataAsync
delegate
Razor<DxComboBox Data="FirstDataSource"
ValueFieldName="@nameof(MyModel.ID)"
TextFieldName="@nameof(MyModel.Name)"
Value="@FirstValue"
ValueChanged="@(async (int? value) => await OnValueChanged(value))" />
<DxComboBox Data=@SecondDataSource
ValueFieldName="@nameof(MyModel.ID)"
TextFieldName="@nameof(MyModel.Name)"
@bind-Value="@SecondValue" />
@code {
IEnumerable<MyModel> FirstDataSource { get; set; }
IEnumerable<string> SecondDataSource { get; set; }
int? FirstValue { get; set; }
string? SecondValue { get; set; }
public class MyModel {
public int ID { get; set; }
public string Name { get; set; }
}
protected override void OnInitialized() {
FirstDataSource = Enumerable.Range(0, 10).Select(i => new MyModel() { ID = i, Name = $"Name {i}" });
}
public async Task<IEnumerable<string>> LoadDataAsyncCore(CancellationToken cancellationToken = default(CancellationToken)) {
if (!FirstValue.HasValue)
return Enumerable.Empty<string>();
return FirstDataSource.Where(i => i.ID % FirstValue == 0).Select(i => i.Name);
}
async Task OnValueChanged(int? value) {
FirstValue = value;
await RefreshData();
}
async Task RefreshData() {
SecondDataSource = await LoadDataAsyncCore();
}
}
Reason for Change
In previous versions, ComboBox/TagBox reinitialized data on every component re-render when the DataAsync
property is used. This can cause side effects and reduce performance. In the current version, you should force the ComboBox/TagBox to fetch data as needed. This approach aligns better with Blazor's architecture and helps us to improve performance.
Impact on Existing Apps
This change affects your application if you use the DataAsync
property to bind the ComboBox/TagBox to data and need to update the data at runtime.
How to Update Existing Apps
Use one of the following approaches:
- Set a key and update it when you need to update data.
- Use the
Data
property instead of theDataAsync
delegate.