c# - Blazor 组件双向数据绑定(bind)

标签 c# blazor 2-way-object-databinding

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

<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;

}

正如预期的那样,编辑父输入会将其值传播到组件,但反之则不然,这是设计使然吗?

我通过此编辑实现了双向行为:

<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; }
}

这是实现双向数据绑定(bind)的最佳实践吗?那么TitleChanged必须手动调用,对吧?是不是像WPF的PropertyChanged?

没有

     if (_Title != value)

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

最佳答案

这是组件之间的双向数据绑定(bind)。此行为(或限制)是设计使然。你所做的,是解决问题的正确方法,我可以大胆地说,这是一种最佳实践,至少根据史蒂夫·安德森,其他人可能会建议不同的方法,例如服务类。

对发生的情况的一些解释:当您对父组件应用更改时,会触发更改事件,组件的状态已更改,并且应重新渲染组件。为了重新渲染父组件,Blazor 会自动调用 StateHasChanged 方法。但是,当子组件上的状态发生更改时,父组件对此一无所知,我们应该通知它。再次强调,在我看来,使用事件回调是一个很好的做法......

希望这有帮助......

编辑...

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.

史蒂夫桑德森

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

首先,您不需要手动调用 StateHasChanged 方法。每当输入事件被触发时就会自动调用;即按下每个键盘按键后。并调用它来重新渲染组件(父组件)。 (注意:人们很容易认为 input 标签是 HTML 输入标签元素,但事实并非如此。)

至于为什么不相反:我认为SteveSanderson的引言已经说得很清楚了。

当你想向父组件传递一个值(这实际上是一个参数,而不是一个 Attribute 属性)时,你需要使用不同的机制,例如事件(SteveSanderson 推荐的;并且与 Angular 中的工作方式相同) )。以下是其执行方式的示例代码。 重要提示:当子组件更改父组件的状态时,我们应该通过手动调用 StateHasChanged 方法让父组件知道其状态已更改并且应该重新渲染。使用 Action 委托(delegate)时确实如此,但我认为 EventCallback 委托(delegate)应该自动调用 StateHasChanged。

组件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> 

如果我的回答对您有帮助,请将其标记为已接受 希望这有帮助...

关于c# - Blazor 组件双向数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134234/

相关文章:

asp.net - Blazor 应用重新部署的最佳实践

c# - 如何在 Amazon S3 中创建文件夹

entity-framework - Blazor 的 IDbContextFactory : when to use CreateDbContextAsync the async version vs CreateDbContext

c# - 比较大量对象

javascript - Blazor在一键onclick事件中执行C#和JS函数

polymer - 如何在 Polymer 中反射(reflect)从 child 到 parent 的变化

android - 如何在 Android 数据绑定(bind)中的属性更改时得到通知?

Angular 2 双向绑定(bind)更新模拟服务常量

c# - XAML 元素填充所有剩余空间

c# - 如何将两个列值添加到列表