2019年12月29日 星期日

ASP.NET Core Blazor元件中的參數傳遞與值變化

ASP.NET Core Blazor元件中的參數傳遞與值變化

更多關於 Blazor 教學影片,可以參考 Blazor 教學影片播放清單 或者 Blazor 快速體驗教學影片撥放清單。也歡迎訂閱本 .NET / Blazor / Xamarin.Forms 影片頻道 。


在這篇關於 Blazor 的參數傳遞與使用變化上的文章,將會進行自我解惑相關問題,所以,將會需要建立一個測試專案,將相關問題在這個專案上實際跑看看,以便知道實際執行結果。
也就是說,若一個參數傳遞某個元件A,且該元件A內部也使用了元件B,而元件B也會接收到來自元件A相同的參數,現在的問題是,要顯示元件A的 Blazor 元件,變更了傳遞參數物件的值,對於元件A與元件B內的參數物件,會有甚麼變化呢?另外,若在元件A中變更了參數物件值,對於元件B與要顯示元件A的那個元件,其參數物件又會有甚麼樣子的變化呢?
首先,建立 Blazr 伺服器端的專案範本來建立一個專案,接著,建立一個方案資料夾,並且在這個資料夾內,建立起四個元件,如下圖
對於 HighLevelComponent [高階元件] 這個元件,將會接收一個參數,並且將這個參數顯示在螢幕上
而對於 HighLevelComponentWithInput [高階元件有 input index] 這個元件,將會接收一個參數,並且將這個參數顯示在螢幕上,而且,還會有一個 input 標籤,透過雙向綁定將這個傳遞進來的參數綁定再一起。
對於 LowLevelComponent [低階元件] 這個元件,將會接收一個參數,並且將這個參數顯示在螢幕上,這個元件除了可以在 index.razor 首頁頁面顯示之外,也會用於底下的 [高階元件有 input index] 這個元件內,以便觀察當在傳遞進來的 Index 有變化的時候,會有甚麼影響。
而對於 HighLevelComponentWithLow [高階元件自我包含低階元件] 這個元件,將會接收一個參數,並且將這個參數顯示在螢幕上,而且,還會顯示 LowLevelComponent [低階元件] 這個元件,當然,也會將同樣的參數傳遞到 [低階元件] 這個元件。
並且將這四個元件,實際用於這個專案的 index.razor 元件中,底下是執行效果
在這篇文章所提到的專案原始碼,可以從 GitHub 下載

HighLevelComponent [高階元件] 這個元件

底下是這個元件的 Blazor 程式碼,可以看到這裡使用了 [Parameter] 這個 C# Attribute 屬性,宣告 HighLevelMessage 這個字串變數為一個參數變數,也就是,這個物件值,可以透過 Blazor 參數傳遞的方式進行變更。
另外,這個 HighLevelMessage 參數也會透過單向綁定方式,顯示在 HTML 頁面上
<div class="card">
    <div class="card-body">
        <h5 class="card-title">高階元件</h5>
        <p class="card-text">@HighLevelMessage</p>
    </div>
</div>

@code {
    [Parameter]
    public string HighLevelMessage { get; set; } = "Higher";
}

HighLevelComponentWithInput [高階元件有 input index] 這個元件

底下是這個元件的 Blazor 程式碼,可以看到這裡使用了 [Parameter] 這個 C# Attribute 屬性,宣告 HighLevelComponentWithInputMessage 這個字串變數為一個參數變數,也就是,這個物件值,可以透過 Blazor 參數傳遞的方式進行變更。
另外,這個 HighLevelComponentWithInputMessage 參數也會透過單向綁定方式,顯示在 HTML 頁面上,而且,這個 HighLevelComponentWithInputMessage 參數,也會透過雙向資料綁定的方式,綁定到 input 這個標記上(使用 @bind-value="HighLevelComponentWithInputMessage")
<div class="card">
    <div class="card-body">
        <h5 class="card-title">高階元件有 input</h5>
        <p class="card-text">@HighLevelComponentWithInputMessage</p>
        <div class="card-text m-3">
            <input @bind-value="HighLevelComponentWithInputMessage" @bind-value:event="oninput" />
        </div>
    </div>
</div>

@code {
    [Parameter]
    public string HighLevelComponentWithInputMessage { get; set; } = "Higher";
}

LowLevelComponent [低階元件] 這個元件

底下是這個元件的 Blazor 程式碼,可以看到這裡使用了兩個 [Parameter] 這個 C# Attribute 屬性,宣告 LowLevelMessage 這個字串變數為一個參數變數與 BackgroundColor 這個字串變數,作為要設定用於 css 背景顏色的支用,也就是,這個物件值,可以透過 Blazor 參數傳遞的方式進行變更。
另外,這個 LowLevelMessage 參數也會透過單向綁定方式,顯示在 HTML 頁面上,這個 BackgroundColor 參數也會透過單向綁定方式,套用到 class 屬性的值上
<div class="card @BackgroundColor">
    <div class="card-body">
        <h5 class="card-title">低階元件</h5>
        <p class="card-text">@LowLevelMessage</p>
    </div>
</div>

@code {
    [Parameter]
    public string LowLevelMessage { get; set; } = "Lower";
    [Parameter]
    public string BackgroundColor { get; set; } = "bg-info";
}

HighLevelComponentWithLow [高階元件自我包含低階元件] 這個元件

底下是這個元件的 Blazor 程式碼,可以看到這裡使用了 [Parameter] 這個 C# Attribute 屬性,宣告 HighLevelWithLowMessage 這個字串變數為一個參數變數,也就是,這個物件值,可以透過 Blazor 參數傳遞的方式進行變更。
另外,這個 HighLevelMessage 參數也會透過單向綁定方式,顯示在 HTML 頁面上
不過,在這個元件內,也同時使用了 LowLevelComponent 這個元件,並且使用了 LowLevelMessage="@HighLevelWithLowMessage" BackgroundColor="bg-success" 語法,將引數傳遞到 LowLevelComponent 這個元件內。
<div class="bg-warning p-4">

    <div class="card">
        <div class="card-body">
            <h5 class="card-title">高階元件自我包含低階元件</h5>
            <p class="card-text">@HighLevelWithLowMessage</p>
        </div>
    </div>
    <LowLevelComponent LowLevelMessage="@HighLevelWithLowMessage"
                       BackgroundColor="bg-success" />
</div>

@code {
    [Parameter]
    public string HighLevelWithLowMessage { get; set; } = "Higher";
}

關於 index.razor 這個元件

現在要把剛剛設計的元件,全部整合在一起,在這裡,將會把這個專案範本內的 index.razor 元件內的宣告與程式碼,修改成為如下面列表
@page "/"

<h1 class="display-5 text-danger">Blazor元件中的參數傳遞與值變化</h1>

<div class="my-3">
    <input @bind-value="UserInput" @bind-value:event="oninput" />
</div>

<div class="card-columns">
    <HighLevelComponent HighLevelMessage="@UserInput" />
    <HighLevelComponentWithInput HighLevelComponentWithInputMessage="@UserInput"/>
    <LowLevelComponent LowLevelMessage="@UserInput" />
    <HighLevelComponentWithLow HighLevelWithLowMessage="@UserInput" />
</div>

@code{
    public string UserInput { get; set; } = "Index";
}

進行測試

現在,來看看所關心的問題之執行結果,首先,會看到執行結果的畫面如下圖
首先,將螢幕左上角的 Input 文字輸入盒內的 Index 文字,修改為 [第一次變更],此時,將會看到底下的效果
在這裡,所有接收到來自於 index.razor 內傳送過去的引數,都會完全變更了
現在,請修改左下角的 input 文字輸入盒,將文字輸入盒的內容修改成為 [第2次變更],此時,執行結果如下圖。
在這裡,將會看到,這樣的操作動作,並不會影響到其他的參數物件值,僅有自己會影響到。
最後,請修改左上角的 input 文字輸入盒,將內容修改為 [第三次變更],網頁內容將會變成底下結果
此時,所有的參數都受到了影響,全部變更成為這次修正的內容




沒有留言:

張貼留言