簡體   English   中英

如何在 Blazor 中通過 @Ref 獲得的 Reference 設置組件屬性

[英]How in Blazor Set component properties through a Reference that obtained by @Ref

我有一個組件,我在頁面變量中設置了它的引用:

<BlazorWebFormsComponents.Button OnClick="@((args) => btnForms_Clicked(formsButton, args))" @ref="formsButton" Text="Forms Button" CssClass="btn btn-primary">
    
</BlazorWebFormsComponents.Button>

在事件處理程序中,我設置了一個按鈕屬性(文本):

Button formsButton;

public void btnForms_Clicked(object sender, MouseEventArgs e)
{                        
    if (sender is Button)
        (sender as Button).Text = "Good Bye";
}

對於大多數 Button 屬性,此代碼不起作用,對於 BackColor 有效,但對於 Text 無效。 blazor 也做了分配線,綠色下划線並說“組件參數“zzz”不應該設置在其組件之外”,那么為什么 Blazor 提供了一個 @Ref 而大多數引用的屬性都無法設置? 還是有辦法使這項工作?

我不是 Blazor 的出口,但也遇到了這個問題。 您可以通過綁定到頁面上的屬性來做到這一點。

<BlazorWebFormsComponents.Button OnClick="@((args) => btnForms_Clicked(formsButton, args))" @ref="formsButton" Text="@ButtonText" CssClass="btn btn-primary">

</BlazorWebFormsComponents.Button>

@code{
    private string ButtonText { get; set; } = "Forms button";

    public void btnForms_Clicked(object sender, MouseEventArgs e)
    {
        ButtonText = "Good bye";
    }
}

我從未使用過@Ref,也不知道如何或何時使用它。

出現警告是因為從代碼中設置[Parameter]屬性會導致渲染樹不同步,並導致組件的雙重渲染。

如果您需要從代碼中設置某些內容,您可以在組件 class 上公開一個公共方法,例如SetText ,它會為您執行此操作。

在內部,組件[Parameter]應該引用一個局部變量。

string _text;
[Parameter] 
public string Text { get => _text; set => SetText(value);}
public void SetText(string value)
{
  _text = value;
}

我不是在推廣這種方法,我更喜歡在@Pidon 的回答中使用這種方法。 此外,您可以考慮 - 也許您有太多參數,應該考慮使用 Options 參數來合並

<Button OnClick="@((args) => btnForms_Clicked(formsButton, args))" @ref="formsButton" Text="Forms Button" CssClass="btn btn-primary">

您的 Button 組件應定義如下:

@code
{
    [Parameter]
    public EventCallback<MouseEventArgs> OnClick {get; set;} 
    [Parameter]
    public string Text {get; set;} 

}

上面的代碼定義了兩個應該從 Parent 組件分配的參數屬性。 父組件是Button組件被實例化的組件。 請注意,您應該將父組件的上述屬性設置為屬性屬性......您不能在組件實例化之外設置它們。 現在這是一個警告,但史蒂夫安德森已經很難過它很快就會成為編譯器錯誤。 這是在父組件中實例化組件的方式:

父.razor

<Button OnClick="@((args) => btnForms_Clicked(args))" @ref="formsButton" 
      Text="_text" CssClass="btn btn-primary">
    
</Button>

@code
{
private Button formsButton;

// Define a local variable wich is bound to the Text parameter
private string _text = "Click me now...";

public void btnForms_Clicked( MouseEventArgs e)
{                        
    _text = "You're a good clicker.";
}
}

注意:當您點擊 Button 組件時,應在 Button 組件中引發單擊事件,並且按鈕組件應將此事件傳播到父組件; 也就是在父組件上執行 btnForms_Clicked 方法,你可以這樣做:

按鈕.razor

<div @onclick="InvokeOnClick">@Text</div>

@code
    {
        [Parameter]
        public EventCallback<MouseEventArgs> OnClick {get; set;} 
        [Parameter]
        public string Text {get; set;} 

        private async Task InvokeOnClick ()
        {
             await OnClick.InvokeAsync(); 
        }
    
    } 

請注意,為了演示如何在 Button 組件中引發事件並將其傳播到父組件,我使用的是 div 元素,但您可以使用按鈕元素等。

@onclick是一個編譯器指令,指示創建一個 EventCallback 'delegate',其值為事件處理程序InvokeOnClick 現在,每當您單擊 div 元素時,都會引發click事件,並調用事件處理程序InvokeOnClick ...從該事件中我們執行 EventCallback 'delegate' OnClick 換句話說,我們調用父組件中定義的 btnForms_Clicked 方法。

那么@ref指令有什么用呢? 您可以使用@ref 指令來獲取對包含要從其父組件調用的方法的組件的引用:假設您定義了一個用作對話框小部件的子組件,並且該組件定義了一個Show方法,當被調用,顯示對話框小部件。 這很好且合法,但切勿嘗試在組件實例化之外更改或設置參數屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM