【问题标题】:blazor editform change eventsblazor 编辑表单更改事件
【发布时间】:2020-08-17 22:38:30
【问题描述】:

我想在 blazor 编辑表单中有一个 InputSelect,它绑定到模型值,并且还有一个 onchange 事件,它可以根据新值更改模型中的其他属性。

绑定到@bind-Value 和@onchange 不起作用(我猜是因为绑定值同时使用输入的值和值更改的属性。

我可以绑定到 oninput,但我想知道是否有更好的方法来做到这一点。

<InputSelect id="inputPeriod" name="inputPeriod" class="form-control" @bind-Value="model.Period" @oninput="periodChanged">


protected void periodChanged(ChangeEventArgs e)
        {}

我可以像这样绑定到 oninput

但理想情况下,我想在模型属性更新后绑定到 @onchange 事件,或者知道最佳实践是什么。如果不使用绑定值,模型验证将不起作用,所以我能想到的唯一替代方法是让更改事件在我的模型的属性中工作,但这似乎是错误的

【问题讨论】:

    标签: onchange blazor model-validation blazor-editform


    【解决方案1】:

    这是一个愚蠢的示例,您必须在其中输入您的姓名,然后选择您的宠物,结果是以您亲爱的宠物为您重命名。该示例描述了在字段更改时如何操作模型:

    <EditForm EditContext="@EditContext">
    <DataAnnotationsValidator />
    
    <div class="form-group">
        <label for="name">Enter your Name: </label>
        <InputText Id="name" Class="form-control" @bind-Value="@person.Name"></InputText>
        <ValidationMessage For="@(() => person.Name)" />
    
    </div>
    <div class="form-group">
        <label for="body">Select your pet: </label>
        <InputSelect @bind-Value="@person.Pet">
            <option value="Cat">Cat</option>
            <option value="Dog">Dog</option>
            <option value="Horse">Horse</option>
            <option value="Lion">Lion</option>
        </InputSelect>
         <ValidationMessage For="@(() => person.Pet)" />
    </div>
    
    <p>
        <button type="submit">Submit</button>
    </p>
    </EditForm>
    
    
     @code
     {
        private EditContext EditContext;
        private Person person = new Person();
    
    
        protected override void OnInitialized()
        {
            EditContext = new EditContext(person);
            EditContext.OnFieldChanged += EditContext_OnFieldChanged;
    
            base.OnInitialized();
        }
    
        // Note: The OnFieldChanged event is raised for each field in the model
        private void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
        {
            if (e.FieldIdentifier.FieldName == "Pet")
            {
    
                person.Name = person.Pet;
    
            }
        }
    
    
        public class Person
        {
            public string ID { get; set; }
            public string Name { get; set; }
            public string Pet { get; set; }
        }
    }
    

    我能想到的唯一替代方法是让更改事件在我的模型的属性中工作,但这似乎是错误的

    完全没有……

    模型不需要实现 INotifyPropertyChanged,但如果他们这样做,您可以轻松地将其连接到 EditContext。这样您就无需使用内置的 Input* 组件 - 您可以改为绑定到常规 HTML 元素并仍然获得修改通知。这为 UI 的呈现方式提供了更大的灵活性,但代价是模型类中的复杂性和样板文件更多。

    希望这会有所帮助...

    【讨论】:

    • 谢谢。这很好用,除了我在日期字段上尝试过,当我输入年份时它触发得太早,所以我必须找到一种方法来检查模型是否有效,然后再更改其他值,但这是一个不同的问题
    • 您可以通过在 OnFieldChanged 事件中调用 EditContext.Validate() 来验证 EditContext,如下所示: if (EditContext.Validate()) { Disabled = null; } else { 禁用 = "禁用"; }
    • 这只适用于标量类型。如果您有多个复杂对象连接到您的模型,并且这些复杂对象恰好与您绑定到的属性具有相同的名称(例如“Id”),那么每当您更改 任何这些复杂对象的 InputSelect 组件。
    【解决方案2】:

    这是一种无需使用双向绑定即可实现您想要的解决方案。相反,该值仅绑定到选择框,这将触发验证。

    <InputSelect 
        id="inputPeriod" name="inputPeriod"      
        value="model.Period"
        class="form-control" 
        @onchange="periodChanged"
    > 
    
    
    
    @code
    {
    
        void periodChanged(ChangeEventArgs e) 
            {
                model.Period = (string) e.Value;
                //your logic... 
            }
    
    }
    

    【讨论】:

    • 感谢您的帮助。这看起来是一个不错的解决方案,但是当我在日期字段上尝试它时,出现运行时错误: InvalidOperationException: Microsoft.AspNetCore.Components.Forms.InputDate`1[System.DateTime] 需要 'ValueExpression' 参数的值。通常这是在使用“绑定值”时自动提供的。
    • 你不能这样编码... InputSelect 是一个组件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 2022-07-07
    相关资源
    最近更新 更多