Blazor - 遍历 EditForm
Blazor - iterate through EditForm
我正在 Blazor.wasm 中构建一个(静态)网站,用户可以在其中上传一些文件。然后我的意图是(在所有文件都通过一些基本检查之后)迭代地呈现一组要求用户完成的字段。只有在他们提交了所有 [Required]
信息并按提交后,才会显示下一个表单。
我在下面包含了一个最小的例子。
if (valid_files == numFiles)
{
for (int counter = 0; counter < num_files; counter++)
{
paramList.Add(new ParamsForm { });
<EditForm Model="@paramList[counter]" OnValidSubmit="@SingleSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
Camera type <br>
<InputText id="cameratype" @bind-Value="@paramList[counter].CameraType" />
</p>
<button type="submit">Submit</button>
</EditForm>
}
<button @onclick="HandleValidSubmit">Upload Data </button>
}
预期的行为是在每次迭代中,onbject ParamsForm
的一个 frech 实例被添加到列表中。然后我们基于该实例创建一个表单并等待用户完成该表单。一旦他们按下 Submit
按钮,for
循环的下一阶段就会开始。提交所有数据并完成 for
循环后,应出现 Upload data
按钮并邀请用户将所有数据提交到服务器。
相反,EditForm ...
部分中的代码 none 正在完成。 IE。 - 我没有看到文本框弹出,我在那里输入的任何代码(例如 @Console.WriteLine("This should show up)
似乎没有被执行。Upload data
按钮没有出现,而是抛出一个错误抱怨index is out of range
,这很奇怪,因为在 for 循环顶部的代码之后,索引不再访问任何元素。
我对 c# 和 HTML 之间的交互还很陌生,所以我想我可以理解为什么我有 不应该 工作,但我不知道我怎样才能写出有用的东西。
如有任何建议,我们将不胜感激。
Blazor的方式对我来说也有点神秘——需要一段时间来适应!我知道 Blazor 有一个 OnAfterRender 事件,这让我觉得它可能不喜欢在这样的循环中让用户输入。或者它可能将 if (valid_files == numFiles)
枚举为 false,因为当标记首次呈现时这些变量尚未初始化。
我会尝试两件事:
(1) 在循环的末尾或设置 valid_files
和 numFiles
的代码之后抛出 StateHasChanged()
并查看它是否满足您的要求。
(2) 可能是这样:我不是在标记中循环,而是在 FileInput
的事件处理程序中构建整个 List<ParamsForm> paramsList
,而是将计数器移动到代码块, 并将 counter++
添加到 SingleSubmit()
方法的末尾。
已经5:00了,刚起床去吃点心就回去睡觉了。让我知道如果事情仍然不顺利,明天我会尝试一个更完整的例子。 :D
关于您的class、您从何处获取文件列表等,我没有太多信息。我建议传递完整的对象而不是单个属性。例如,我宁愿在 ParamsForm
class 中使用 IBrowserFile File {get; set;}
而不是 string FileName
。那样的话,如果我决定——哦,我想要这个或那个 属性——它已经在那里了。
无论如何,希望这里的内容可能有用:
@if (CurrentForm is not null)
{
<EditForm Model="CurrentForm" OnValidSubmit="@SingleSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
Camera type <br>
<InputText id="cameratype" @bind-Value="CurrentForm.CameraType" />
</p>
<button type="submit">Submit</button>
</EditForm>
@if (IsComplete) // Don't show upload button until you're done
{
<button @onclick="DoUploads">Upload Data </button>
}
@DisplayMessage
}
@code {
class ParamsForm { public string FileName; public string CameraType; } // Just a placeholder
List<ParamsForm> ParamsList = new List<ParamsForm>();
ParamsForm CurrentForm { get; set; }
int counter = 0;
List<string> FileNames;
bool IsComplete = false;
string DisplayMessage = "";
void InitializeForms()
{
// I don't know your class, so just an example
foreach (var item in FileNames)
{
bool IsValid = false;
// check file validity
if (IsValid) ParamsList.Add(new ParamsForm() { FileName = item });
}
if(ParamsList.Count > 0)
CurrentForm = ParamsList[0];
}
void SingleSubmit()
{
// Do stuff with CurrentForm
if (++counter >= ParamsList.Count) IsComplete = true;
else CurrentForm = ParamsList[counter];
}
async Task DoUploads()
{
// Do stuff with your ParamsList
int UploadCounter = 0;
foreach (ParamsForm item in ParamsList){
DisplayMessage = "Uploading " + UploadCounter + " of " + ParamsList.Count;
StateHasChanged();
// Do the Upload;
}
DisplayMessage = "Finished.";
}
}
我正在 Blazor.wasm 中构建一个(静态)网站,用户可以在其中上传一些文件。然后我的意图是(在所有文件都通过一些基本检查之后)迭代地呈现一组要求用户完成的字段。只有在他们提交了所有 [Required]
信息并按提交后,才会显示下一个表单。
我在下面包含了一个最小的例子。
if (valid_files == numFiles)
{
for (int counter = 0; counter < num_files; counter++)
{
paramList.Add(new ParamsForm { });
<EditForm Model="@paramList[counter]" OnValidSubmit="@SingleSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
Camera type <br>
<InputText id="cameratype" @bind-Value="@paramList[counter].CameraType" />
</p>
<button type="submit">Submit</button>
</EditForm>
}
<button @onclick="HandleValidSubmit">Upload Data </button>
}
预期的行为是在每次迭代中,onbject ParamsForm
的一个 frech 实例被添加到列表中。然后我们基于该实例创建一个表单并等待用户完成该表单。一旦他们按下 Submit
按钮,for
循环的下一阶段就会开始。提交所有数据并完成 for
循环后,应出现 Upload data
按钮并邀请用户将所有数据提交到服务器。
相反,EditForm ...
部分中的代码 none 正在完成。 IE。 - 我没有看到文本框弹出,我在那里输入的任何代码(例如 @Console.WriteLine("This should show up)
似乎没有被执行。Upload data
按钮没有出现,而是抛出一个错误抱怨index is out of range
,这很奇怪,因为在 for 循环顶部的代码之后,索引不再访问任何元素。
我对 c# 和 HTML 之间的交互还很陌生,所以我想我可以理解为什么我有 不应该 工作,但我不知道我怎样才能写出有用的东西。
如有任何建议,我们将不胜感激。
Blazor的方式对我来说也有点神秘——需要一段时间来适应!我知道 Blazor 有一个 OnAfterRender 事件,这让我觉得它可能不喜欢在这样的循环中让用户输入。或者它可能将 if (valid_files == numFiles)
枚举为 false,因为当标记首次呈现时这些变量尚未初始化。
我会尝试两件事:
(1) 在循环的末尾或设置 valid_files
和 numFiles
的代码之后抛出 StateHasChanged()
并查看它是否满足您的要求。
(2) 可能是这样:我不是在标记中循环,而是在 FileInput
的事件处理程序中构建整个 List<ParamsForm> paramsList
,而是将计数器移动到代码块, 并将 counter++
添加到 SingleSubmit()
方法的末尾。
已经5:00了,刚起床去吃点心就回去睡觉了。让我知道如果事情仍然不顺利,明天我会尝试一个更完整的例子。 :D
关于您的class、您从何处获取文件列表等,我没有太多信息。我建议传递完整的对象而不是单个属性。例如,我宁愿在 ParamsForm
class 中使用 IBrowserFile File {get; set;}
而不是 string FileName
。那样的话,如果我决定——哦,我想要这个或那个 属性——它已经在那里了。
无论如何,希望这里的内容可能有用:
@if (CurrentForm is not null)
{
<EditForm Model="CurrentForm" OnValidSubmit="@SingleSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
Camera type <br>
<InputText id="cameratype" @bind-Value="CurrentForm.CameraType" />
</p>
<button type="submit">Submit</button>
</EditForm>
@if (IsComplete) // Don't show upload button until you're done
{
<button @onclick="DoUploads">Upload Data </button>
}
@DisplayMessage
}
@code {
class ParamsForm { public string FileName; public string CameraType; } // Just a placeholder
List<ParamsForm> ParamsList = new List<ParamsForm>();
ParamsForm CurrentForm { get; set; }
int counter = 0;
List<string> FileNames;
bool IsComplete = false;
string DisplayMessage = "";
void InitializeForms()
{
// I don't know your class, so just an example
foreach (var item in FileNames)
{
bool IsValid = false;
// check file validity
if (IsValid) ParamsList.Add(new ParamsForm() { FileName = item });
}
if(ParamsList.Count > 0)
CurrentForm = ParamsList[0];
}
void SingleSubmit()
{
// Do stuff with CurrentForm
if (++counter >= ParamsList.Count) IsComplete = true;
else CurrentForm = ParamsList[counter];
}
async Task DoUploads()
{
// Do stuff with your ParamsList
int UploadCounter = 0;
foreach (ParamsForm item in ParamsList){
DisplayMessage = "Uploading " + UploadCounter + " of " + ParamsList.Count;
StateHasChanged();
// Do the Upload;
}
DisplayMessage = "Finished.";
}
}