[英]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.