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