简体   繁体   English

Blazor 中双向绑定和禁用可编辑文本字段的最佳方法是什么?

[英]What is the best method for two way binding and disabling editable text fields in Blazor?

For POCOs with lots of fields I find it really convenient to have a simple form/component binding structure like this对于有很多字段的 POCO,我发现有一个像这样的简单表单/组件绑定结构真的很方便

< input type="text" bind="@Person.FirstName" /> < input type="text" bind="@Person.FirstName" />

< input type="text" bind="@Person.LastName" /> < input type="text" bind="@Person.LastName" />

< input type="text" bind="@Person.Address" /> < input type="text" bind="@Person.Address" />

Where I then have save or create new buttons/events to deal with object at a time situations.然后我保存或创建新的按钮/事件以一次处理 object 的情况。 In other words the entire object is bound to an editable component making life super easy to bring objects from the DB for editing and back into the db.换句话说,整个 object 都绑定到一个可编辑的组件,这使得将对象从数据库中取出进行编辑并返回到数据库中变得非常容易。

What I find annoying are situations where I have to both display an object's details but make sure parts of it are locked/un-editable based on certain conditions.我觉得烦人的是我必须既显示对象的详细信息又要确保它的某些部分根据特定条件被锁定/不可编辑的情况。 Let's say I can't change LastName for some business logic reason.假设由于某些业务逻辑原因我无法更改 LastName。 This:这:

< input type="text" bind="@Person.LastName" disabled="@somecondition" /> < input type="text" bind="@Person.LastName" disabled="@somecondition" />

is unsafe as users can potentially inspect the page, modifying the disabled flag and still cause the two way binding to be enabled and changes overwritten in the existing save event.是不安全的,因为用户可能会检查页面,修改禁用标志并仍然导致启用双向绑定并在现有保存事件中覆盖更改。 The workarounds I find are annoying eg, you can use if code blocks to switch between textboxes and plain-text binding, or you just do all the business logic in the event which introduced more logic for error reporting.我发现的变通方法很烦人,例如,您可以使用 if 代码块在文本框和纯文本绑定之间切换,或者您只是在引入更多错误报告逻辑的事件中执行所有业务逻辑。

Here is a compromise that I think "works":这是我认为“有效”的妥协:

if(some_protective_condition) { < input type="text" bind="@Person.Address" /> } if(some_protective_condition) { < input type="text" bind="@Person.Address" /> }

else { < span>@Person.Addressv< /span>}否则{ <span>@Person.Addressv< /span>}

If I understand correctly most of these workarounds essentially play with the DOM or some aspect of visibility ensuring the editable control does not get rendered.如果我理解正确的话,这些变通办法中的大多数本质上都是与 DOM 或可见性的某些方面一起使用,以确保不会呈现可编辑控件。 What is the coding pattern would you guys use for these situations of interface level locking?对于这些接口级别锁定的情况,你们会使用什么编码模式?

EDIT/TLDR: Looking for the best/safe least code pattern to maintain two-way binding, display a value and make it editable/non-editable in certain situations.编辑/TLDR:寻找最佳/安全最少的代码模式来维护双向绑定,显示一个值并使其在某些情况下可编辑/不可编辑。

Suggestions welcome as I am trying to build good solid long term habits.欢迎提出建议,因为我正在努力养成良好的长期习惯。

Tried several techniques.尝试了几种技术。 Looking for the best option if I have missed something.如果我错过了什么,寻找最佳选择。

I think what your looking for is InputBase .我认为您要寻找的是InputBase Creating a component that inherits from InputBase is going to give you access to additional features like validation styles ( @CssClass ) on top of two-way binding.创建一个继承自InputBase的组件将使您能够访问双向绑定之上的其他功能,例如验证 styles ( @CssClass )。 You can use the @attributes on the input inside your component to add readonly and disabled attributes according to your POCO.您可以根据您的 POCO 在组件内的输入上使用@attributes添加readonlydisabled属性。

For InputBase have a peek at my answer here .对于InputBase ,请在此处查看我的回答。 Disabling the input by adding @attributes="GetAttributes()" to the html input.通过将@attributes="GetAttributes()"添加到 html 输入来禁用输入。

    [Parameter] public bool IsReadOnly { get; set; } = false;
    [Parameter] public bool IsDisabled { get; set; } = false;
    Dictionary<string,object> GetAttributes()
    {
        // Required should be handled by the DataAnnotation.
        var dict = new Dictionary<string, object>();
        if (IsReadOnly)
        {
            dict.Add("readonly", true);
        }
        if (IsDisabled)
        {
            dict.Add("disabled", true);
        }

        return dict;
    }

I think the 'Blazor Way' to integrate business rules into your views is to use AuthorizeView...我认为将业务规则集成到您的视图中的“Blazor 方式”是使用 AuthorizeView...

<AuthorizeView Policy="CanEditAddress">
    <Authorized>
        < input type="text" bind="@Person.Address" />
    </Authorized>
    <NotAuthorized>
        < span>@Person.Addressv< /span>
    </NotAuthorized>
</AuthorizeView>

The docs show how to populate authorization policies using cascading parameters... https://learn.microsoft.com/en-us/as.net/core/blazor/security/?view=as.netcore-7.0#expose-the-authentication-state-as-a-cascading-parameter文档显示如何使用级联参数填充授权策略... https://learn.microsoft.com/en-us/as.net/core/blazor/security/?view=as.netcore-7.0#expose-the -身份验证状态作为级联参数

If your rules are not really 'business rules' but are 'presentation rules' (like your forms have an edit mode vs a display mode) then the above pattern is still a good way to go. That is, I would create a class named 'PresentationView' that is the equivalent of AuthorizationView but for presentation rules.如果您的规则不是真正的“业务规则”而是“表示规则”(例如您的 forms 具有编辑模式与显示模式),那么上述模式仍然是 go 的好方法。也就是说,我将创建一个名为 class 'PresentationView' 相当于 AuthorizationView 但用于表示规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM