代码之家  ›  专栏  ›  技术社区  ›  Ahmad Salim

客户端。NET 8 web应用服务器双向绑定未绑定到模型,事件未被触发

  •  0
  • Ahmad Salim  · 技术社区  · 6 月前

    我在一个DateTimeServer应用程序中使用Syncfusion的SfTextBox组件。我已经绑定了 @bind-Value 在我的模型中添加一个属性 ValueChange 事件以获取额外的逻辑。

    然而 价值变更 事件未触发,绑定属性仍为空。

        <SfTextBox @bind-value=@Value
                   Placeholder=@Placeholder
                   Enabled=@IsEnabled
                   [email protected]
                   CssClass="" />
    
    public partial class SignInComponent : ComponentBase
    {
          [Inject]
          public IIdentityViewService IdentityViewService { get; set; }
    
          [Inject]
          public AuthenticationStateProvider AuthStateProvider { get; set; }
    
          public ComponentState State { get; set; }
          public IdentityComponentException Exception { get; set; }
    
          public SignInView SignInView { get; set; }
          public TextBoxBase SignInEmailTextBox { get; set; }
          public TextBoxBase SignInPasswordTextBox { get; set; }
          public ButtonBase SubmitButton { get; set; }
          public SpinnerBase Spinner { get; set; }
    
          protected override void OnInitialized()
          {
              SignInView = new SignInView();
              State = ComponentState.Content;
          }
    }
    
    public partial class TextBoxBase : ComponentBase
    {
         [Parameter]
         public string Value { get; set; }
    
         [Parameter]
         public string Placeholder { get; set; }
    
         [Parameter]
         public string CssClass { get; set; }
    
         [Parameter]
         public EventCallback<string> ValueChanged { get; set; }
    
         [Parameter]
         public bool IsDisabled { get; set; }
    
         public bool IsEnabled => IsDisabled is false;
    
         public async Task SetValue(string value)
         {
             this.Value = value;
             await ValueChanged.InvokeAsync(this.Value);
         }
    
         private Task OnValueChanged(ChangeEventArgs changeEventArgs)
         {
             this.Value = changeEventArgs.Value.ToString();
             //InvokeAsync(StateHasChanged);
             return ValueChanged.InvokeAsync(this.Value);
         }
    
         public void Disable()
         {
             this.IsDisabled = true;
             InvokeAsync(StateHasChanged);
         }
    
         public void Enable()
         {
             this.IsDisabled = false;
             InvokeAsync(StateHasChanged);
         }
    }
    
    <div class="py-6 flex flex-col gap-5">
        <div>
            <TextBoxBase
                 @ref=@SignInEmailTextBox
                 @[email protected]
                 Placeholder="Your email ?"
                 CssClass="w-full py-3 px-6 ring-1 ring-gray-300 rounded-xl placeholder-gray-600 bg-transparent transition disabled:ring-gray-200 disabled:bg-gray-100 disabled:placeholder-gray-400 invalid:ring-red-400 focus:invalid:outline-none" />
        </div>
        <div class="flex flex-col items-end">
            <TextBoxBase 
                 @ref=@SignInPasswordTextBox
                 @[email protected]
                 Placeholder="What's the secret word ?"
                 CssClass="w-full py-3 px-6 ring-1 ring-gray-300 rounded-xl placeholder-gray-600 bg-transparent transition disabled:ring-gray-200 disabled:bg-gray-100 disabled:placeholder-gray-400 invalid:ring-red-400 focus:invalid:outline-none" />
               <a href="/forgotten/password" type="reset" class="w-max p-3 -mr-3">
                   <span class="text-sm tracking-wide text-blue-600">Forgot password ?</span>
               </a>
        </div>
        <div>
            <ButtonBase 
                   @ref=@SubmitButton 
                   OnClick=@SignInAsync 
                   Label="Login"
                   CssClass="w-full px-6 py-3 rounded-xl bg-sky-500 transition hover:bg-sky-600 focus:bg-sky-600 active:bg-sky-800" />
            <SpinnerBase @ref=@Spinner />
        </div>
    </div>
    
    2 回复  |  直到 6 月前
        1
  •  1
  •   MrC aka Shaun Curtis    6 月前

    您需要正确地整理绑定,即设置getter以获取提供的 Value 设置器通过调用 ValueChanged 回拨。
    下面是一个使用标准的示例 InputText 因为我不使用SF。我很确定SF TextBox的工作原理是一样的。我还展示了如何在不创建自定义控件的情况下实现您所展示的功能。

    注意:一旦你正确理解了逻辑,就不需要乱打电话给 StateHasChanged 通过代码。

    另请参阅此问答,其中显示了直接继承自Text控件的另一种方法- https://stackoverflow.com/a/78661731/13065781

    已设置绑定的基本自定义控件:

    <InputText disabled="@IsDisabled" class="@CssClass" 
        placeholder="@this.Placeholder"
        @bind-Value:get="@Value" 
        @bind-Value:set="SetValue"/>
    
    @code {
        [Parameter] public string? Value { get; set; }
        [Parameter] public string? Placeholder { get; set; }
        [Parameter] public string? CssClass { get; set; }
        [Parameter] public EventCallback<string> ValueChanged { get; set; }
        [Parameter] public bool IsDisabled { get; set; }
    
        public bool IsEnabled => IsDisabled is false;
    
        public async Task SetValue(string? value)
        {
            this.Value = value;
            await ValueChanged.InvokeAsync(this.Value);
        }
    }
    

    还有一个演示页面:

    @page "/"
    
    <PageTitle>Home</PageTitle>
    
    <h1>Hello, world!</h1>
    
    Welcome to your new app.
    
    <EditForm Model="_model">
        <div class="mb-2">
    
            <InputText disabled="@_isDisabled" 
                class="form-control" 
                placeholder="Enter Your Name" 
                @bind-Value="_model.Name" />
    
        </div>
    
        <div class="mb-2">
            <TextBoxBase CssClass="form-control" 
            IsDisabled="_isDisabled" 
            Placeholder="Enter A Value" 
            @bind-Value="_model.Value" />
    
        </div>
    </EditForm>
    
    <div class="mb-2">
        <button class="btn btn-primary" @onclick="OnDisable">Disable</button>
    </div>
    
    <div class="bg-dark text-white m-1 p-1">
        <pre>Name: @_model.Name</pre>
        <pre>Value: @_model.Value</pre>
    </div>
    @code {
        private Model _model = new Model();
        private bool _isDisabled;
    
        private void OnDisable()
        {
            _isDisabled = !_isDisabled;
        }
    
        public class Model
        {
            public string? Name { get; set; }
            public string? Value { get; set; }
        }
    }
    

    最后一个音符。您不需要获取引用来编辑这样的组件:

    public TextBoxBase SignInPasswordTextBox { get; set; }
    

    一切都应该通过参数来实现。

        2
  •  0
  •   Ahmad Salim    6 月前

    在@MrC(又名Shaun Curtis)的帮助下进行了一点更改应用get和@bind Value:set触发了事件

    <SfTextBox @bind-value:get=@Value
           @bind-value:set=@SetValue
           Placeholder=@Placeholder
           Enabled=@IsEnabled
           [email protected]
           CssClass="" />