在MVC视图/剃刀页面中使用RenderComponentAsync(Blazor WebAssembly)

时间:2019-10-22 13:56:32

标签: asp.net-core razor blazor blazor-server-side blazor-client-side

我已对整个问题进行了编辑,以更好地理解

我的示例解决方案包含2个项目

  • MVC App + Blazor服务器
  • 剃刀类库

Razor类库具有一个非常简单的组件“ Awesome.razor”:

<h3>@name</h3>

<button @onclick="@(() => name = name.ToUpper())">Upper case me</button>

@code {
    string name = "Mr. Blazor";

}

MVC应用具有Home / Index.cshtml:

看起来像这样:

<div id="MyComponent">
    @(await Html.RenderComponentAsync<Awesome>(RenderMode.ServerPrerendered))
</div>

如果我运行应用程序(<root>/home/index

我可以单击按钮,“超赞”组件起作用。

是否可以使用相同的技术(Html.RenderComponentAsync),而不是使用Blazor Server使用Blazor WebAssembly?

我做了一些尝试来使其工作(通过使用Blazor WebAssembly模板并将其与MVC App集成来进行尝试/错误),但是无法使其工作。我想知道我做错了什么吗,或者RendercomponentAsync是否只能与Blazor Server结合使用。

可以在此处找到整个源代码(无需尝试WebAssembly): https://github.com/geeForceOne/MvcWithBlazor

更新

显然Blazor WebAssembly支持RenderComponentAsync

通过使他的示例应用程序适应此Daniel Roth,我设法部分实现了我想要的目标(归功于https://github.com/geeForceOne/BlazorWebAssemblyWithPrerendering)。

我尝试使用try n错误尝试其他方法,并提出了以下解决方案:

在Blazor.Client项目的Startup.cs中,我注册了两个组件:

app.AddComponent<Counter>("counter");
app.AddComponent<Awesome>("awesome");

然后,我创建了两个Razor页面MyTest.cshtml和MyTest2.cshtml。虽然MyTest.cshtml完全可以满足我的要求并可以正常工作:

<awesome>
    @(await Html.RenderComponentAsync<Awesome>(RenderMode.Static))
  </awesome>

<counter>
    @(await Html.RenderComponentAsync<Counter>(RenderMode.Static))
</counter>

<script src="_framework/blazor.webassembly.js"></script>

在MyTest2.chshtml上不起作用

@* To make this work, you need to 
    call
        app.AddComponent<Awesome>("awesome"); 
    before 
        app.AddComponent<Counter>("counter");
    in
        BlazorWebAssemblyWithPrerendering.Client.Startup
*@

<awesome>
    @(await Html.RenderComponentAsync<Awesome>(RenderMode.Static))
</awesome>


<script src="_framework/blazor.webassembly.js"></script>

我的问题:我在正确的道路上吗(我需要更改使其正常工作)?还是我可以按照Daniel Roth的原始样本以这种方式只运行一个组件?

1 个答案:

答案 0 :(得分:0)

这是我的新答案,已经看过您的应用并进行了调查:

您无法在浏览器上执行Razor Pages应用程序或MVC应用程序中嵌入的Razor组件。换句话说,您的组件不会通过WebAssembly执行。

即使您在应用程序中引用Blazor WebAssembly应用程序,引用的组件也不会在使用WebAssembly的浏览器上运行。我已经在您的MVC解决方案中创建了默认的Blazor WebAssembly App,并在您的MVC项目中添加了对其的引用。然后,我在Index.Html中渲染了Counter,它运行良好。但是计数器组件未使用WebAssembly在浏览器上执行。

当我使用此版本时:

@(await Html.RenderComponentAsync<MyBlazorAssembly.Pages.Counter>(RenderMode.ServerPrerendered))

Counter组件是交互式的,递增并显示新值。 使用RenderMode.Server时会产生相同的行为。在这两种情况下,Counter组件都是交互式的,这是由于选择了RenderMode,并且该组件已在服务器上预呈现。选择RenderMode.Static时,组件将呈现为静态HTML,并且无法进行交互。

这正是您尝试在WebAssembly上运行Awesome组件时发生的事情。不幸的是,它被呈现为静态HTML,并且当您单击按钮时,不会引发任何响应...未触发事件处理程序,没有执行lambda表达式,也没有办法将文本大写(您可以这样做)使用纯JavaScript)。

You can read here about the rendering modes.

请,如果我不够清楚,请随时向我提问...