I am learning Blazor. I have no experience with component-based programming.
I have two components: a DateRangePicker
and a RadzenCheckBox
.
<RadzenFieldset Text="Test Component">
<DateRangePicker @ref="calendar" />
<div>
<Radzen.Blazor.RadzenCheckBox TValue="bool" Change="@((args) => txtBoxChange(args))" />
<RadzenLabel Text="Check" />
</div>
</RadzenFieldset>
Now, the requirement is simple. If the checkbox is clicked, show two calendars and show one calendar if it's unchecked.
I wrote the following code:
@code{
DateRangePicker calendar;
public void txtBoxChange(bool args)
{
if (args == true) //shows one calendar when checked
calendar.ShowOnlyOneCalendar = true;
else //shows two calendars when unchecked
calendar.ShowOnlyOneCalendar = false;
}
}
This works fine.
But I get a warning:
Component parameter 'ShowOnlyOneCalendar' should not be set outside of its component.
I have read some blogs about this warning, which suggest making parent and child component relationship for communication between components. But these are not parent and child.
What am I doing wrong? What is the best way to achieve such a requirement and not have this warning?
What am I doing wrong?
Instead of using an imperative programming (component.Parameter1=v1
) way, a Component Parameter is supposed be passed in a declarative syntax :
<Component Parameter1="@v1" Parameter2="@v2" />
Note that you're assigning values to [Parameter]
directly:
calendar.ShowOnlyOneCalendar = true;
That's why Blazor
complains. In other words, you need change it in following way:
<DateRangePicker ShowOnlyOneCalendar="@showOnlyOne" />
Always follow this pattern like other SPA:
(render)
Data -----------> View
For example, your code could be rewritten as below:
<DateRangePicker ShowOnlyOneCalendar="@flag" />
...
@code{
private bool flag = false;
public void txtBoxChange(bool args)=> flag = args;
}
(Here we have a flag
data, and we should render the view according to the data)
Or if you do want to use an imperative programming way, you need to invoke a method and avoid assigning values to the [Parameter]
properties directly.
<DateRangePicker @ref="calendar" />
...
@code{
DateRangePicker calendar;
public void txtBoxChange(bool args)
{
calendar.A_Wrapper_Method_That_Changes_The_Parameter(args);
// as suggested by @Uwe Keim,
// `InvokeAsync(StateHasChanged)` is better than `StateHasChanged()`
InvokeAsync(StateHasChanged);
}
}