Blazor组件TwoWay数据绑定 [英] Blazor Component TwoWay Databinding

查看:250
本文介绍了Blazor组件TwoWay数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以这种方式制作了Blazor组件:

I've made a Blazor component this way:

<input bind-value-oninput="Title" />


@functions {

    [Parameter] string Title { get; set; }

    [Parameter] EventCallback<string> TitleChanged { get; set; }
}

父母:

@page "/fetchdata"

Parent:<input bind-value-oninput="Title" /> - Child:<Comp bind-Title="Title"></Comp>



@functions {
    string Title;

}

如预期的那样,编辑父输入将其值传播到组件

as expected editing the parent input propagate it's value to the component but not viceversa, is that by design right?

我通过这种编辑实现了两种行为:

I achieved two-way behaviour with this edit:

<input bind-value-oninput="Title" />


@functions {
    string _Title { get; set; }
    [Parameter] string Title 

    {
        get { return _Title; }
        set
        {
            Console.WriteLine($"{value}->{_Title}");



            if (_Title != value)
            {
                _Title = value;
                TitleChanged.InvokeAsync(value);
            }


        }
    }

    [Parameter] EventCallback<string> TitleChanged { get; set; }
}

这是实现双向数据绑定的最佳实践吗?然后必须手动调用TitleChanged,对吗?就像WPF的PropertyChanged吗?

Is this the best practice to achieve two-way data binding? Then TitleChanged must be called manually, right? Is it like PropertyChanged of WPF?

没有

     if (_Title != value)

代码进入循环,有人可以解释为什么?

the code goes in loop, someone could explain why?

推荐答案

这是组件之间的双向数据绑定。此行为(或限制)是设计使然。您所做的是解决问题的正确方法,我敢说最好的做法,至少根据Steve Anderson的说法,其他人可能会建议其他方法,例如服务等级。

This is a two-way data binding between components. This behavior (or limitation) is by design. What you do, is the correct way to solve it, and I may venture to say, a best practice, at least according Steve Anderson, others may suggest different methods, such as a service class.

有关发生的情况的一些解释:将更改应用于父组件时,将触发change事件,该组件的状态已更改,并且该组件应重新呈现。要重新渲染父组件,Blazor会自动调用StateHasChanged方法。但是,当子组件的状态发生变化时,父组件对此一无所知,因此我们应该通知它。同样,在我看来,使用事件回叫是一个好习惯……

Some explanation of what is going on: When you apply a change to the parent component, the change event is triggered, the state of the component has changed, and the component should be re-rendered. To re-render the parent component, the StateHasChanged method is called by Blazor automatically. But when a state is changed on the child component, the parent component is ignorant of this, and we should notify it of this. Again, using event call backs for this is a good practice, to my mind...

希望这会有所帮助...。

Hope this helps....

编辑...。


通常,参数流向下,即从父对象到
的孩子,而不是在另一个方向,因为渲染流程在
的那个方向进行。这就是为什么没有一种方法可以将参数
传递给上游(例如,传递给布局),因为这样就没有单个
定义的渲染顺序。

In general the parameter flow goes downwards, i.e., from parent to child, not in the other direction, because the rendering flow goes in that direction. That's why there isn't a way to pass parameters upstream (e.g., to a layout), because then there's be no single defined render order.

SteveSanderson

Marco:我不明白是为什么在父级上调用StateHasChanged的原因数据从父级流向子级,而不是相反。

Marco: What I don't understand is why calling StateHasChanged on the parent causes the data to flow from the parent to the child and not the opposite.

首先,您无需手动调用StateHasChanged方法。每当触发输入事件时,都会自动调用它。即在按下每个键盘键之后。然后调用它来重新渲染Component(父级)。 (注意:很容易想到输入标签是HTML输入标签元素,但事实并非如此。)

First off, you don't manually call the StateHasChanged method. It is automatically called whenever the input event is triggered; that is after each keyboard key is pressed. And it is called to rerender the Component(parent). ( Note: It is tempting to think that the input tag is an HTML input tag element, but it is not so.)

为什么不是相反:我认为 SteveSanderson 的引号很清楚。

As for why not the opposite: I think the quotation by SteveSanderson made it very clear.

当您要传递值时(这实际上是一个参数,但不是Attribute属性)到父组件,您需要使用其他机制(例如事件)(由SteveSanderson推荐;其工作方式与Angular相同)。下面是示例代码如何执行。
重要:当父组件的状态从子组件更改时,我们应该让父组件知道其状态已更改,并且应该通过手动调用来重新呈现StateHasChanged方法。使用Action委托时,这是正确的,尽管我认为EventCallback委托应该自动调用StateHasChanged。

When you want to pass a value (This is actually a parameter, but not an Attribute property) to the Parent Component, you need to use a different mechanism such as events (recommended by SteveSanderson; and work the same like in Angular). Below is sample code how it is performed. Important: When the state of the Parent Component is being changed from a child component, we should let the Parent Component to know that its state has changed and that it should rerender, by manually calling the StateHasChanged method. This is true when using the Action delegate, though I think that the EventCallback delegate is supposed to call StateHasChanged automatically.

组件A.cshtml

// Define a method in the parent component which will be called 
// from the child component when the user tap the button residing 
// in the child component. This method has a string parameter passed
// from the child component
public void GetValueFromChild(string value)
 {
        // Do somethig with value
  } 

组件B.cshtml

// When the user click the button the method GetValueFromChild
// defined on the parent component is called

<button class="btn" onclick=@(() => OnAddValue("some string value"))>Add</button>

    @functions
{
    // Define an Action delegate property which stores a reference
    // to A.GetValueFromChild
    // Parameters
    [Parameter] Action<string> OnAddValue{ get; set; }
}

A.cshtml

// Here (in the parent component) you place the child component and
// set its OnAddValue to the name of the method to be called
<B OnAddValue = "GetValueFromChild"></B> 

如果可以帮助您解决
,请标记我的答案为已接受希望这会有所帮助...

Please mark my answer as accepted if it helped you out Hope this helps...

这篇关于Blazor组件TwoWay数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆