我正在尝试找出一些简单数据的主视图/详细视图。我有一个食谱列表,每个食谱都有一个成分列表。
我有一个“食谱”页面,其中列出了所有食谱,并且运行良好。 我有一个RecipeDetail剃刀组件,一旦从“配方”页面选择了配方,就应该获取“成分表”。
我尝试过各种方法。我已经尝试通过将食谱及其成分完全填充到RecipeDetail组件中来进行数据绑定,但是由于数据结构的原因,GetJsonAsync方法检测到循环引用,并引发异常。我尝试通过绑定到“食谱”页面上变量的“参数”将从“食谱”页面选择的食谱ID传递到“食谱详细信息”页面,但从未触发数据获取。
@page "/recipes"
@using BlazorApp.Shared.Models
@inject HttpClient Http
<h1>Recipes</h1>
@if(RecipesArray != null)
{
@foreach (var r in RecipesArray)
{
<h3 @onclick="@(() => SelectRecipe(r))">@r.Title</h3>
}
}
<RecipeDetail RecipeId="@SelectedRecipeId"></RecipeDetail>
@code {
Recipe[] RecipesArray;
int SelectedRecipeId;
protected override async Task OnInitializedAsync()
{
RecipesArray = await Http.GetJsonAsync<Recipe[]>("Recipes");
}
protected void SelectRecipe(Recipe recipe)
{
SelectedRecipeId = recipe.Id;
}
}
以下内容在技术上是可行的,但是当我取消注释提取时,它将不再起作用。该应用程序冻结。
@using BlazorApp.Shared.Models
@inject HttpClient Http
<h1>RecipeId = @selectedRecipeId</h1>
@if (Ingredients != null && Ingredients.Length > 0)
{
<h1>@RecipeId</h1>
<ul>
@foreach (var item in Ingredients)
{
<li>@item.Ingredient.ToString()</li>
}
</ul>
}
@code {
private int selectedRecipeId;
RecipeIngredient[] Ingredients;
[Parameter]
public int RecipeId
{
get { return selectedRecipeId; }
set
{
selectedRecipeId = value;
//if (value > 0)
// Ingredients = Http.GetJsonAsync<RecipeIngredient[]>($"Recipes/{RecipeId}").Result;
}
}
}
我很乐意修复JSON错误并仅绑定到传递的对象,但是我也找不到解决方案。我尝试了[JsonIgnore]属性,但这没有帮助。
即使Json提取是固定的,我认为我仍然有一个用例可以在参数更改后重新提取数据,因此我想了解两种情况下我做错了什么。
答案 0 :(得分:0)
尝试(我尚未测试过)...
private void sendData()
{
if (!(btOutputStream == null)){
try {
btOutputStream.write("Hello".getBytes());
ToastMaker("Data is sent");
} catch (IOException e) {
e.printStackTrace();
}
}
}
答案 1 :(得分:0)
为了传递组件参数,您应该在子组件中定义两个参数属性:
@code {
[Parameter]
public int RecipeId { get; set; }
[Parameter]
public EventCallback<int> RecipeIdChanged { get; set; }
}
现在,无论何时在父组件中选择一个配方,从而更改了SelectedRecipeId变量的值,RecipeId参数属性的值都会更新,因此您可以通过任何方式使用新值,包括发送http请求到服务器。
在父组件中,您应该拥有这个
<RecipeDetail @bind-RecipeId="@SelectedRecipeId"></RecipeDetail>
注意 <RecipeDetail @bind-RecipeId="@SelectedRecipeId"></RecipeDetail>
本质上等同于写作:
<RecipeDetail @bind-RecipeId="SelectedRecipeId" @bind-RecipeId:event="RecipeIdChanged" />
注意:将值从父组件传递到子组件的另一种方法是使用AppState模式。您可以看到如何使用此模式here
您还可以使用CascadingValue组件来获得相同的功能
希望这会有所帮助
答案 2 :(得分:-1)
这是我为RecipeDetail想到的解决方案
@using BlazorApp.Shared.Models
@inject HttpClient Http
@if (Ingredients != null && Ingredients.Length > 0)
{
<ul>
@foreach (var item in Ingredients)
{
<li>@item.ToString()</li>
}
</ul>
}
@code {
RecipeIngredient[] Ingredients;
[Parameter]
public int RecipeId { get; set; }
protected override async Task OnParametersSetAsync()
{
if (RecipeId != 0)
{
await LoadRecipeDetails(RecipeId);
}
}
private async Task LoadRecipeDetails(int RecipeId)
{
Ingredients = await Http.GetJsonAsync<RecipeIngredient[]>($"Recipes/{RecipeId}");
}
}