调用函数后 Blazor 列表未更新
Blazor list not updating after calling functions on it
我正在 blazor web-assembly (.NET 6) 中使用视频播放器开发网页。此 blazor 网页使用 Url 的列表,该列表未正确更新。
一般页面逻辑:该页面创建了一个 IList Videos 的自声明 class ExcerciseVideo。此 IList 应在初始化后更改,具体取决于两个函数的用户输入。
RepeatExercises:此函数在按下按钮并重复特定视频指定次数后调用。这是必要的,因为必须重复几个视频。我想通过使用播放列表来执行此操作,而不是循环播放视频。
ModifyUrl:此函数在按下按钮后调用,应该只更改具有真正双面属性的视频。应将第一个视频的变量 currentUrl 设置为 Url1(当 sidePlayNext == "left" 时),将第二个相同的视频设置为 Url2(当 sidePlayNext == "对)。
我已经尽可能地简化了代码。
@page "/"
@inject IJSRuntime theJavaScriptEngine;
<!-- Buttons for interaction -->
<button @onclick="StartVideo">Start video</button>
<button @onclick="RepeatExcercises">Repeat Excercises</button>
<button @onclick="ModifyUrl"> Modify Url (of Two Sided Videos)</button>
<!-- Video Element -->
<div class="align-content-center">
<video id="videoTagId" autoplay width="1080" height="720" @onended="NextVideo">
<source id="videoSourceId" src="@Videos[selected_video_id].CurrentUrl" type="video/mp4"/>
</video>
</div>
<!-- Developer output -->
@foreach(var v in Videos)
{
<li><code>Name: </code>@v.Name</li>
<li><code>Video Current URl</code>@v.CurrentUrl</li>
<li><code>Video URl 1</code>@v.Url1</li>
<li><code>Video URL 2</code>@v.Url2</li>
<li><code>Two Sided</code>@v.TwoSided</li>
<li>...</li>
}
@code
{
public int selected_video_id { get; set; } = 0;
public IList<ExcerciseVideo>? Videos; // The list we use to store the Videos
public int Repetitions { get; set; } = 2; // we want each exercise two times
public string sidePlayNext {get; set; } = "left";
public class ExcerciseVideo
{
public string Name { get; set; }
public string CurrentUrl { get; set; }
public string Url1 { get; set; }
public string Url2{ get; set; } // right hand side of each excercise
public bool TwoSided { get; set; }
}
protected override void OnInitialized()
{
Videos = new List<ExcerciseVideo>()
{
new ExcerciseVideo {
Name="Excercise A",
CurrentUrl = "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4",
Url1="https://backtrainingapp.blob.core.windows.net/backtrainingvideos/20220220_184806[1].mp4",
Url2="https://backtrainingapp.blob.core.windows.net/backtrainingvideos/20220220_184806[1].mp4",
TwoSided=false},
new ExcerciseVideo {
Name="Excercise B",
CurrentUrl = "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4",
Url1="https://backtrainingapp.blob.core.windows.net/backtrainingvideos/20220220_184632[1].mp4",
Url2="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4",
TwoSided=true}
};
}
public void RepeatExcercises()
{
// obtain values of the Video List
int old_video_count = Videos.Count;
int my_index = 0;
// Create a copy of the Video List
IList<ExcerciseVideo> originalVideos = new List<ExcerciseVideo>(Videos);
Videos.Clear(); // Clear the list --> we need a clean list for item insertion (in order to not have old items included)
// we loop over the list to repeat Videos
// and insert them
for (int l = 0; l < old_video_count; l++)
{
for (int repeats = 0; repeats < Repetitions; repeats++)
{
Videos.Insert(my_index, originalVideos[l]);
my_index++; // increment the index
}
}
StateHasChanged(); // Make sure that the changes are updated
}
// Modify the Url of twoSided Videos
public void ModifyUrl()
{
for (int m = 0; m < Videos.Count; m++)
{
// check whether a video is twosided
if (Videos[m].TwoSided == true)
{
// check whether left side should be played
// set Url1 in this case as value
if (sidePlayNext == "left")
{
Videos[m].CurrentUrl = Videos[m].Url1;
Console.WriteLine(sidePlayNext);
Console.WriteLine(Videos[m].CurrentUrl);
sidePlayNext = "right";
}
// check whether right side should be played
// set Url2 in this case as value
else if (sidePlayNext == "right")
{
Videos[m].CurrentUrl = Videos[m].Url2;
Console.WriteLine(sidePlayNext);
Console.WriteLine(Videos[m].CurrentUrl);
sidePlayNext = "left";
}
}
// All other cases in which no two sided videos are present
// --> Current URl should correspond to Url1
else if (Videos[m].TwoSided == false)
{
Videos[m].CurrentUrl = Videos[m].Url1;
Console.WriteLine("No Direction");
Console.WriteLine(Videos[m].CurrentUrl);
}
}
StateHasChanged();
}
protected void StartVideo()
{
selected_video_id = 0;
theJavaScriptEngine.InvokeVoidAsync("loadVideo");
}
protected void NextVideo()
{
selected_video_id = selected_video_id + 1;
theJavaScriptEngine.InvokeVoidAsync("loadVideo");
}
}
测试和遇到的问题(另请参阅 blazor fiddle:https://blazorfiddle.com/s/3ltiwlv3):
- 请检查视频下方的输出 --> 视频加载时的列表似乎已正确填充
- 然后按“重复练习”按钮 --> 在视频下方的输出中,视频似乎按预期重复
- 然后按“修改 Url”按钮 --> 看练习 B。不幸的是,第一个和第二个“练习 B”的电流 Url 是相等的.练习 B 的第二个条目中的列表不会更新为 Url2.
中的值
我已经在控制台应用程序中测试了“RepeatExcercises”和“ModifyUrl”功能,它们在那里运行良好,并按预期更新了“视频”列表。 最终,我还想更新 VideoPlayer 的 src 属性。我已经尝试使用 blazor 绑定,但也了解到在已经加载时重置视频源很困难(尤其是Url 在列表的指定索引上......) - 我该怎么做?
<!-- Video Element -->
<div class="align-content-center">
<video id="videoTagId" autoplay width="1080" height="720" @onended="NextVideo">
<source id="videoSourceId" src="@Videos[selected_video_id].CurrentUrl" type="video/mp4"/>
</video>
</div>
我已经阅读了所有可以在网上找到的类似问题,但现在完全卡住了。非常感谢帮助。
致以最诚挚的问候,谢谢
最大值
Blazor 运行良好。
Q1:更新url
问题出在您的代码上。当您按 'Repeat Exercises' 时,您将插入 ExcerciseVideo
Excercise B
的两倍。请注意,您是否只有 Excercise B
的一个实例在列表中插入两次(同一实例对象在列表中两次)。
当您遍历列表时,您发现 Excercise B
两次:
A
A
B
B <--- // Is the same ExcerciseVideo instance as previous
然后,在第一个 B 上,您将 url 更改为某个值,然后在第二个 B(与之前的 B 相同)上,您将 url.
改回
要更正您的拼写错误,只需将函数更改为:
public void RepeatExcercises()
{
// obtain values of the Video List
int old_video_count = Videos.Count;
int my_index = 0;
// Create a copy of the Video List
IList<ExcerciseVideo> originalVideos = new List<ExcerciseVideo>(Videos);
Videos.Clear(); // Clear the list
// we loop over the list to repeat Videos
// and insert them
for (int l = 0; l < old_video_count; l++)
{
for (int repeats = 0; repeats < Repetitions; repeats++)
{
var new_video = new ExcerciseVideo { // <-- Important part
Name=originalVideos[l].Name,
CurrentUrl = originalVideos[l].CurrentUrl,
Url1=originalVideos[l].Url1,
Url2=originalVideos[l].Url2,
TwoSided=originalVideos[l].TwoSided};
Videos.Insert(my_index, new_video);
my_index++; // increment the index
}
}
StateHasChanged(); // Make sure that the changes are updated
}
Q2:更新视频src
关于您问题的第二部分,更新 src 属性,完整解释如下:
我正在 blazor web-assembly (.NET 6) 中使用视频播放器开发网页。此 blazor 网页使用 Url 的列表,该列表未正确更新。
一般页面逻辑:该页面创建了一个 IList Videos 的自声明 class ExcerciseVideo。此 IList 应在初始化后更改,具体取决于两个函数的用户输入。
RepeatExercises:此函数在按下按钮并重复特定视频指定次数后调用。这是必要的,因为必须重复几个视频。我想通过使用播放列表来执行此操作,而不是循环播放视频。
ModifyUrl:此函数在按下按钮后调用,应该只更改具有真正双面属性的视频。应将第一个视频的变量 currentUrl 设置为 Url1(当 sidePlayNext == "left" 时),将第二个相同的视频设置为 Url2(当 sidePlayNext == "对)。
我已经尽可能地简化了代码。
@page "/"
@inject IJSRuntime theJavaScriptEngine;
<!-- Buttons for interaction -->
<button @onclick="StartVideo">Start video</button>
<button @onclick="RepeatExcercises">Repeat Excercises</button>
<button @onclick="ModifyUrl"> Modify Url (of Two Sided Videos)</button>
<!-- Video Element -->
<div class="align-content-center">
<video id="videoTagId" autoplay width="1080" height="720" @onended="NextVideo">
<source id="videoSourceId" src="@Videos[selected_video_id].CurrentUrl" type="video/mp4"/>
</video>
</div>
<!-- Developer output -->
@foreach(var v in Videos)
{
<li><code>Name: </code>@v.Name</li>
<li><code>Video Current URl</code>@v.CurrentUrl</li>
<li><code>Video URl 1</code>@v.Url1</li>
<li><code>Video URL 2</code>@v.Url2</li>
<li><code>Two Sided</code>@v.TwoSided</li>
<li>...</li>
}
@code
{
public int selected_video_id { get; set; } = 0;
public IList<ExcerciseVideo>? Videos; // The list we use to store the Videos
public int Repetitions { get; set; } = 2; // we want each exercise two times
public string sidePlayNext {get; set; } = "left";
public class ExcerciseVideo
{
public string Name { get; set; }
public string CurrentUrl { get; set; }
public string Url1 { get; set; }
public string Url2{ get; set; } // right hand side of each excercise
public bool TwoSided { get; set; }
}
protected override void OnInitialized()
{
Videos = new List<ExcerciseVideo>()
{
new ExcerciseVideo {
Name="Excercise A",
CurrentUrl = "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4",
Url1="https://backtrainingapp.blob.core.windows.net/backtrainingvideos/20220220_184806[1].mp4",
Url2="https://backtrainingapp.blob.core.windows.net/backtrainingvideos/20220220_184806[1].mp4",
TwoSided=false},
new ExcerciseVideo {
Name="Excercise B",
CurrentUrl = "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4",
Url1="https://backtrainingapp.blob.core.windows.net/backtrainingvideos/20220220_184632[1].mp4",
Url2="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4",
TwoSided=true}
};
}
public void RepeatExcercises()
{
// obtain values of the Video List
int old_video_count = Videos.Count;
int my_index = 0;
// Create a copy of the Video List
IList<ExcerciseVideo> originalVideos = new List<ExcerciseVideo>(Videos);
Videos.Clear(); // Clear the list --> we need a clean list for item insertion (in order to not have old items included)
// we loop over the list to repeat Videos
// and insert them
for (int l = 0; l < old_video_count; l++)
{
for (int repeats = 0; repeats < Repetitions; repeats++)
{
Videos.Insert(my_index, originalVideos[l]);
my_index++; // increment the index
}
}
StateHasChanged(); // Make sure that the changes are updated
}
// Modify the Url of twoSided Videos
public void ModifyUrl()
{
for (int m = 0; m < Videos.Count; m++)
{
// check whether a video is twosided
if (Videos[m].TwoSided == true)
{
// check whether left side should be played
// set Url1 in this case as value
if (sidePlayNext == "left")
{
Videos[m].CurrentUrl = Videos[m].Url1;
Console.WriteLine(sidePlayNext);
Console.WriteLine(Videos[m].CurrentUrl);
sidePlayNext = "right";
}
// check whether right side should be played
// set Url2 in this case as value
else if (sidePlayNext == "right")
{
Videos[m].CurrentUrl = Videos[m].Url2;
Console.WriteLine(sidePlayNext);
Console.WriteLine(Videos[m].CurrentUrl);
sidePlayNext = "left";
}
}
// All other cases in which no two sided videos are present
// --> Current URl should correspond to Url1
else if (Videos[m].TwoSided == false)
{
Videos[m].CurrentUrl = Videos[m].Url1;
Console.WriteLine("No Direction");
Console.WriteLine(Videos[m].CurrentUrl);
}
}
StateHasChanged();
}
protected void StartVideo()
{
selected_video_id = 0;
theJavaScriptEngine.InvokeVoidAsync("loadVideo");
}
protected void NextVideo()
{
selected_video_id = selected_video_id + 1;
theJavaScriptEngine.InvokeVoidAsync("loadVideo");
}
}
测试和遇到的问题(另请参阅 blazor fiddle:https://blazorfiddle.com/s/3ltiwlv3):
- 请检查视频下方的输出 --> 视频加载时的列表似乎已正确填充
- 然后按“重复练习”按钮 --> 在视频下方的输出中,视频似乎按预期重复
- 然后按“修改 Url”按钮 --> 看练习 B。不幸的是,第一个和第二个“练习 B”的电流 Url 是相等的.练习 B 的第二个条目中的列表不会更新为 Url2. 中的值
我已经在控制台应用程序中测试了“RepeatExcercises”和“ModifyUrl”功能,它们在那里运行良好,并按预期更新了“视频”列表。 最终,我还想更新 VideoPlayer 的 src 属性。我已经尝试使用 blazor 绑定,但也了解到在已经加载时重置视频源很困难(尤其是Url 在列表的指定索引上......) - 我该怎么做?
<!-- Video Element -->
<div class="align-content-center">
<video id="videoTagId" autoplay width="1080" height="720" @onended="NextVideo">
<source id="videoSourceId" src="@Videos[selected_video_id].CurrentUrl" type="video/mp4"/>
</video>
</div>
我已经阅读了所有可以在网上找到的类似问题,但现在完全卡住了。非常感谢帮助。
致以最诚挚的问候,谢谢 最大值
Blazor 运行良好。
Q1:更新url
问题出在您的代码上。当您按 'Repeat Exercises' 时,您将插入 ExcerciseVideo
Excercise B
的两倍。请注意,您是否只有 Excercise B
的一个实例在列表中插入两次(同一实例对象在列表中两次)。
当您遍历列表时,您发现 Excercise B
两次:
A
A
B
B <--- // Is the same ExcerciseVideo instance as previous
然后,在第一个 B 上,您将 url 更改为某个值,然后在第二个 B(与之前的 B 相同)上,您将 url.
改回要更正您的拼写错误,只需将函数更改为:
public void RepeatExcercises()
{
// obtain values of the Video List
int old_video_count = Videos.Count;
int my_index = 0;
// Create a copy of the Video List
IList<ExcerciseVideo> originalVideos = new List<ExcerciseVideo>(Videos);
Videos.Clear(); // Clear the list
// we loop over the list to repeat Videos
// and insert them
for (int l = 0; l < old_video_count; l++)
{
for (int repeats = 0; repeats < Repetitions; repeats++)
{
var new_video = new ExcerciseVideo { // <-- Important part
Name=originalVideos[l].Name,
CurrentUrl = originalVideos[l].CurrentUrl,
Url1=originalVideos[l].Url1,
Url2=originalVideos[l].Url2,
TwoSided=originalVideos[l].TwoSided};
Videos.Insert(my_index, new_video);
my_index++; // increment the index
}
}
StateHasChanged(); // Make sure that the changes are updated
}
Q2:更新视频src
关于您问题的第二部分,更新 src 属性,完整解释如下: