我面临着一个非常奇怪的奇怪行为,只有一个blazor页面。我有一个主要的blazor页面,里面有几个自定义组件。其中一个组件有自己的EditContext和Model。此外,在该组件中,每当字段中的值发生变化时,我都需要计算一些公式。为此,我为OnFieldChanged添加了一个事件侦听器。出于某种原因,我找不到,有时当一些内部组件变量发生变化,并且作为事件参数传递的模型是组件本身,而不是我的上下文模型时,事件就会被触发。这意味着当局部变量而不是模型字段发生更改时,它会被激发。
第一次渲染组件时不会发生这种情况。随着它的发展,每当任何字段值发生变化时都会计算公式,经过3或4次计算后,它就会开始发生。
这导致了一个无限循环,因为当公式值更改时,它将触发重新计算公式的事件,并再次触发该事件。
当内部公式值发生变化时,它实际上不应该触发事件。
此外,我还附上了一张调试屏幕截图。
请看一下我的代码:
<EditForm EditContext="@_editContextProduct" style="margin:0px">
<DataAnnotationsValidator/>
//ALL MY FIELDS HERE
</EditForm >
@code{
private CommercialEvaluationProductContextModel _commercialEvaluationProductContextModel = new ();
private EditContext _editContextProduct;
protected async override Task OnInitializedAsync()
{
_editContextProduct = new EditContext(_commercialEvaluationProductContextModel);
_editContextProduct.OnFieldChanged += ProductEditContext_OnFieldChanged;
}
//formulas declaration
private int _formulaPacksPerStore =0;
private decimal _formulaSizeofPrice =0;
private decimal _formulaRetailerMargin =0;
private decimal _formulaRevenue =0;
private decimal _formulaMargin =0;
private decimal _formulaCogs =0;
private int _formulaPacksPerRun = 0;
private int _formulaProductionFrequency = 0;
private decimal _formulaCogsPerPack = 0;
private void ProductEditContext_OnFieldChanged(object sender,FieldChangedEventArgs e)
{
DoCalculateFormulas();
}
private async void DoCalculateFormulas()
{
_formulaPacksPerStore = _commercialEvaluationProductContextModel.ExpectedAnnualPackVolume /
Math.Max(1,_commercialEvaluationProductContextModel.ListingDuration) /
Math.Max(1,_commercialEvaluationProductContextModel.DistributionValue);
_formulaSizeofPrice = _commercialEvaluationProductContextModel.RetailSalePrice * _commercialEvaluationProductContextModel.ExpectedAnnualPackVolume;
_formulaRetailerMargin = _formulaSizeofPrice * (_commercialEvaluationProductContextModel.RetailerMargin / 100.0M);
_formulaRevenue = _formulaSizeofPrice - _formulaRetailerMargin;
_formulaMargin = _formulaRevenue * (_commercialEvaluationProductContextModel.Margin/100.0M);
_formulaCogs = _formulaRevenue - _formulaMargin;
_formulaPacksPerRun = _commercialEvaluationProductContextModel.ExpectedAnnualPackVolume / Math.Max(1,_commercialEvaluationProductContextModel.ListingDuration);
_formulaProductionFrequency = 365/Math.Max(1,_commercialEvaluationProductContextModel.ListingDuration);
_formulaCogsPerPack = _formulaKepakCogs / Math.Max(1,_commercialEvaluationProductContextModel.ExpectedAnnualPackVolume);
}
}
public class CommercialEvaluationProductContextModel
{
public int Id { get; set; }
[StringLength(maximumLength: 200, MinimumLength = 3)]
[Required]
public string Name { get; set; }
[Required(ErrorMessage = "Choose the product state")]
[Range(1, 99900, ErrorMessage = "Invalid product state")]
public Int16 ProductStateId { get; set; }
public ProductState? ProductState { get; set; }
[Range(1, 99900, ErrorMessage = "Choose the listing type")]
public Int16 ListingTypeId { get; set; }
public ListingType? ListingType { get; set; }
[Range(1, 99900, ErrorMessage = "Choose duration of listing")]
public Int16 ListingTimeIntervalId { get; set; }
public TimeInterval? TimeInterval { get; set; }
[Required(ErrorMessage = "Inform duration of listing")]
[Range(1, 9999999, ErrorMessage = "Invalid duration of listing")]
public int ListingDuration { get; set; }
[Range(1, 32000, ErrorMessage = "Invalid distribution")]
public Int16 DistributionTypeId { get; set; }
public DistributionType? DistributionType { get; set; }
[Required(ErrorMessage = "Inform the distribution value")]
[Range(1, 99999999, ErrorMessage = "Invalid duration of listing")]
public int DistributionValue { get; set; }
[Required(ErrorMessage = "Inform the expected annual pack volume")]
[Range(1, 99999999, ErrorMessage = "Invalid expected annual pack volume")]
public int ExpectedAnnualPackVolume { get; set; }
[Range(1, 99999, ErrorMessage = "Invalid currency")]
public Int16 CurrencyId { get; set; }
public Currency? Currency { get; set; }
[Range(typeof(decimal), "0.1", "99999999999.99", ErrorMessage = "Invalid retail sales price")]
public decimal RetailSalePrice { get; set; }
[Range(typeof(decimal), "0.1", "99999999999.99", ErrorMessage = "Invalid margin")]
public decimal Margin{ get; set; }
[Range(typeof(decimal), "0.1", "99999999999.99", ErrorMessage = "Invalid retail margin")]
public decimal RetailerMargin { get; set; }
[MinLength(3, ErrorMessage = "Minimum of 3 characters")]
public string SalesRational { get; set; }
[MinLength(3, ErrorMessage = "Minimum of 3 characters")]
public string CategoryRational { get; set; }
[Range(1, 99900, ErrorMessage = "Invalid expected annual pack volume")]
public Int16 EstimatedProductWeightMeasureUnitId { get; set; }
public MeasureUnit? MeasureUnit { get; set; }
[Range(typeof(decimal), "0.1", "99999999999.99", ErrorMessage = "Invalid Estimated Product Weight")]
public decimal EstimatedProductWeight { get; set; }
[Range(1, 99900, ErrorMessage = "Invalid expected annual pack volume")]
public int NumberPouchesperInner { get; set; }
public string StatusId { get; set; }
}
问题的屏幕截图
始终将控件绑定到属性而非字段。