[英]In Blazor, How to @bind and then fire @onchange in a dynamic model
Model:
public class FiltersModel
{
public CheckBoxListWithTitle Brand { get; set; }
}
public class CheckBoxListWithTitle
{
public List<FilterCheckBox> CheckBoxes { get; set; }
}
public class FilterCheckBox
{
public string Value { get; set; }
public bool Checked { get; set; }
}
Razor:
@foreach (var item in Model.Brand.CheckBoxes)
{
<label>
@item.Value
<input type="checkbox" @onchange="@FilterChangedBrand" />
</label>
}
@代碼:
public FiltersModel Model { get; set; } // Initialized in OnParametersSet
private void FilterChangedBrand(UIChangeEventArgs e)
{
string newCheckedBrand = e.Value.ToString();
// Now How to Find and Set the relevant Model property to newCheckedBrand
FiltersChanged?.Invoke(Model);
}
如何在 FilterChangedBrand 方法中找到相關的 Model 屬性並將其設置為 newCheckedBrand。
或者在復選框標記中使用 @bind="@item.Checked" ,然后在選中的 state 復選框更改時引發事件?
由於無法使用@bind 和@onchange,您必須純粹在代碼中進行更改。 最簡單的方法是使用 lambda 捕獲item
Razor
@foreach (var item in Model.Brand.CheckBoxes)
{
<label>
@item.Value
<input type="checkbox" @onchange="(e) => FilterChangedBrand(item, e)" />
</label>
}
@代碼
public FiltersModel Model { get; set; } // Initialized in OnParametersSet
public event Action<FiltersModel> FiltersChanged;
private void FilterChangedBrand(FilterCheckBox item, ChangeEventArgs e)
{
// here you do work of @bind
item.Checked = !item.Checked;
string newCheckedBrand = e.Value.ToString();
// Now How to Find and Set the relevant Model property to newCheckedBrand
FiltersChanged?.Invoke(Model);
}
替代和更復雜的方法,如果您想使用例如 WPF 重用您的 UI,這可能會有所幫助,即將該事件級聯放置在 model 本身中。
public class CheckBoxListWithTitle
{
private List<FilterCheckBox> items = new List<FilterCheckBox>();
public IReadOnlyList<FilterCheckBox> CheckBoxes => items.AsReadOnly();
public event EventHandler ModelChanged;
public void Add(FilterCheckBox item)
{
item.CheckedChanged += this.Item_CheckedChanged;
this.items.Add(item);
}
private void Item_CheckedChanged(object sender, EventArgs e)
{
ModelChanged.Invoke(this, EventArgs.Empty);
}
}
public class FilterCheckBox
{
public string Value { get; set; }
public bool Checked { get; set; }
public event EventHandler CheckedChanged;
}
如您所見, CheckBoxListWithTitle
將處理所需事件的傳播。 在 Razor 你只訂閱CheckBoxListWithTitle.ModelChanged
另一種選擇是在有界 object 中使用 INotifyPropertyChanged 接口。
public class RowToApprove : INotifyPropertyChanged
{
private bool _approved;
public string AddressLine { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Approved
{
get => _approved;
set
{
if (value == _approved) return;
_approved = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后在您的頁面中,注冊到 ItemOnPropertyChanged 事件。
item.PropertyChanged += ItemOnPropertyChanged;
並在那里做你的工作:
private void ItemOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
//Do something
}
您的項目可能如下所示:
<input type="checkbox" @bind-value="@(context.Approved)" />
感謝@bind-value:event
,這個答案實際上會做到這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.