簡體   English   中英

剃刀組件中的C#StateHasChanged()不強制 <video> 標簽以加載/更改mp4播放,僅使用javascript似乎有效

[英]C# StateHasChanged() in a razor component does not force <video> tag to load/change the mp4 playing, only using javascript seems to work

我正在嘗試使用服務器端的blazor。 我試圖在剃刀組件的標簽中設置多個按鈕來設置/更改播放的.mp4文件。 我發現完成這項工作的唯一方法是從剃刀組件中的OnParametersSet()通過IJSRuntime:InvokeVoidAsync()調用javascript函數。 javascript函數位於_Host.cshtml中。 對於應該是一個簡單問題的解決方案,這似乎是一個非常丑陋的解決方案。

我嘗試在OnClick按鈕函數中使用StateHasChanged()。 當我查看chrome中的html渲染時,h1-header標簽和源src =“ NewFile”顯示為更新,並且當單擊按鈕但未加載新視頻時,h1標簽在頁面上正確更改。 我的猜測是,這與在其自己的線程上播放的視頻有關,或者視頻標簽本身沒有變化。 我只是不明白如何從razor / c#做到這一點。

由於生成錯誤,因此將Javascript代碼添加到了文件:_Html.cshtml

  <script>
        function loadVideo (strNewVideo)
        {
            document.getElementById('videoSourceId').src = strNewVideo;
            document.getElementById("videoTagId").load();
        }
    </script>

播放視頻的簡單組件... File:VideoPlayer.razor

@inject IJSRuntime theJavaScriptEngine;

<div class="align-content-center">
    <h1>@this.m_strRenderMe</h1>
    <video id="videoTagId" autoplay width="1080" height="720">
        <source id="videoSourceId" src=@this.m_strRenderMe type="video/mp4" />
    </video>
</div>

@code {
    ElementReference theVideoTag;

    [Parameter]
    public string strVideoFilePath { get; set; }

    private string m_strRenderMe;

    protected override void OnParametersSet()
    {
        this.m_strRenderMe = this.strVideoFilePath;

        theJavaScriptEngine.InvokeVoidAsync("loadVideo", this.m_strRenderMe);

        this.StateHasChanged();
    }
}

剃刀頁面上方帶有組件,文件中包含4個按鈕:Counter.razor

@page "/counter"

@using UseBlazorToReadPowerPoint.Classes

@inject CPersistantAppState  thePersistantAppState


<VideoPlayer strVideoFilePath=@thePersistantAppState.m_strVideoPath></VideoPlayer>

<button class="btn btn-primary" @onclick="PlayVideo_1">Video 1</button>
<button class="btn btn-primary" @onclick="PlayVideo_2">Video 2</button>
<button class="btn btn-primary" @onclick="PlayVideo_3">Video 3</button>
<button class="btn btn-primary" @onclick="PlayVideo_4">Video 4</button>

@code {

    void PlayVideo_1()
        {
        thePersistantAppState.m_strVideoPath = "videos/Video-1.mp4";
        }

    void PlayVideo_2()
    {
        thePersistantAppState.m_strVideoPath = "videos/Video-2.mp4";
    }

    void PlayVideo_3()
    {
        thePersistantAppState.m_strVideoPath = "videos/Video-3.mp4";
    }

    void PlayVideo_4()
    {
        thePersistantAppState.m_strVideoPath = "videos/Video-4.mp4";
    }

}

保留所選文件名。 文件:CPersistantAppState.cs

namespace UseBlazorToReadPowerPoint.Classes
{
    public class CPersistantAppState
    {
        public string m_strVideoPath;
    }
}

列出的代碼有效。 我只是不知道如何在沒有JavaScript調用的情況下使這項工作有效。 似乎必須有一種更清潔的方式來執行此操作。

問題不StateHasChangeg() ,而是關於html的Video標簽

通常,僅當您通過更改元素的src屬性或添加或刪除嵌套在media元素自身中的元素對可用於media元素的源集進行了動態更改時,此方法才有用。 load()將重置元素並重新掃描可用的源,從而使更改生效

這意味着更改src屬性后必須執行調用load 您目前無法從blazor調用load ,這意味着您應該通過IJSRuntime調用它:

開拓者代碼

<div class="align-content-center">
    <h1>@m_strRenderMe[currentVideo]</h1>
    <button @onclick="ChangeVideo">Change video</button>
    <video id="videoTagId" autoplay width="1080" height="720">
        <source id="videoSourceId" src="@m_strRenderMe[currentVideo]" type="video/mp4" />
    </video>
</div>

@code
{
    int currentVideo = 0;
    string[] m_strRenderMe = new string[] {
        "https://.../videoplayback-1.mp4",
        "https://.../videoplayback-2.mp4"
    };
    protected void ChangeVideo()
    {
        currentVideo = (currentVideo + 1) % 2;
        theJavaScriptEngine.InvokeVoidAsync("loadVideo");
    }
}

JS代碼

<script>
    function loadVideo ()
    {
        document.getElementById("videoTagId").load();
    }
</script>

BlazorFiddle檢查一下。

暫無
暫無

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

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