14

我正在学习 Blazor。我没有基于组件的编程经验。

我有两个组件: aDateRangePicker和 a RadzenCheckBox

<RadzenFieldset Text="Test Component">
    <DateRangePicker @ref="calendar" />
    <div>
        <Radzen.Blazor.RadzenCheckBox TValue="bool" Change="@((args) => txtBoxChange(args))" />
        <RadzenLabel Text="Check" />
    </div>
</RadzenFieldset>

现在,要求很简单。如果单击该复选框,则显示两个日历,如果未选中则显示一个日历。

我写了以下代码:

@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;
    }
}

这工作正常。

但我得到一个警告:

不应在其组件之外设置组件参数“ShowOnlyOneCalendar”。

我已经阅读了一些有关此警告的博客,其中建议建立父子组件关系以进行组件之间的通信。但这些不是父母和孩子。

我究竟做错了什么?实现此类要求且没有此警告的最佳方法是什么?

4

1 回答 1

13

我究竟做错了什么?

不是使用命令式编程 ( component.Parameter1=v1) 方式,而是应该以声明性语法传递组件参数:

<Component Parameter1="@v1"  Parameter2="@v2" />

请注意,您将值[Parameter]直接分配给:

calendar.ShowOnlyOneCalendar = true;

这就是Blaozr抱怨的原因。换句话说,您需要通过以下方式更改它:

<DateRangePicker ShowOnlyOneCalendar="@showOnlyOne"  />

怎么修

像其他SPA一样始终遵循这种模式:

      (render)
Data -----------> View

例如,您的代码可以重写如下:

<DateRangePicker ShowOnlyOneCalendar="@flag" />
...

@code{
    private bool flag = false;
    public void txtBoxChange(bool args)=> flag = args;
}

(这里我们有一个flag数据,我们应该根据数据渲染视图)

或者,如果您确实想使用命令式编程方式,则需要调用方法并避免[Parameter]直接将值分配给属性。

<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); 
    }
}
于 2020-01-02T07:51:15.517 回答