在 blazor 应用程序之外使用 blazor 组件(例如 knockoutjs)

Using blazor components outside of blazor app (eg. knockoutjs)

我正在做一个迁移项目。我是团队中唯一的 JS 开发人员,其他人都是 C# 开发人员。 我们正在寻求迁移我们现有的用 .Net MVC Knockoutjs 编写的应用程序。 由于我们团队的大部分成员都是 C# 开发人员,我们正在尝试 blazor。

由于整个应用程序重写需要时间,我们希望以 blazor 组件的形式逐个重写应用程序,并一次导出这些组件以在现有的 knockoutjs 应用程序中重用。

这将使我们能够从淘汰赛转移到 blazor,同时继续支持和维护现有应用程序。

我已经将 angular 元素视为一种方式,但是,正如我提到的,我们想试一试 blazor。我很好奇我们是否可以将 blazor 组件导出到其他应用程序并允许它们之间的数据流。

感谢任何help/suggestions。

谢谢

如果您想一次用一个 blazor 组件替换 MVC 页面上的所有 javascript,您可以尝试这个过程,它对我有用。

首先,将您的 MVC 项目更新或转换为 .Net 5.0.402。 它可能适用于早期版本,但我还没有测试过。

在您的 MVC 解决方案中,添加一个 Blazor Web 程序集应用程序项目。 这是 Web 程序集组件项目。

在 MVC 视图中,在您希望呈现 Blazor 组件的位置添加:

@using myawesomewasmprojectnamespace.Pages

<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered"/>

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

“@using”声明指的是 blazor web assembly 应用程序项目,Pages 目录。 'typeof(Counter)'类型是指默认的blazor web assembly app项目中的Counter.razor组件,visual studio供应。

我假设您将能够编写自己的 Blazor 组件以与 Counter.razor 组件交换。

在 MVC 项目的 _Layout.cshtml 中,或 MVC 视图的 <head> 标记所在的任何位置,为每个包含 blazor 组件的页面添加 <head> 标记:

<base href="/"/>

将 'Microsoft.AspNetCore.Components.WebAssembly.Server' 包添加到您的 MVC 项目。

在您的 MVC 依赖项、项目引用中添加对 blazor web 程序集应用程序项目的引用。

在 MVC 应用程序 Startup.cs、'public void Configure(IApplicationBuilder app, IWebHostEnvironment env)' 方法中,添加以下内容:

app.UseBlazorFrameworkFiles();

在 blazor web assembly 应用程序项目 Program.cs 文件中,注释掉以下行以停止应用程序查找 '<div id="app"></div>'

//builder.RootComponents.Add<App>("#app");

最后,从 blazor web assembly 应用程序项目的 wwwroot 目录中删除 favicon,因为它会与 MVC 发生冲突。

然后将 'Counter' 组件添加到您的 MVC 视图。

要将不同的组件添加到不同的视图,请将其插入:

@using myawesomewasmprojectnamespace.Pages

<component type="typeof(Myawsomecomponentnamecompletelydifferentfromanymvccontrolleroractionname)" render-mode="WebAssemblyPrerendered"/>

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

并启动你的 blazor 组件:

@page "/myawsomecomponentnamecompletelydifferentfromanymvccontrolleroractionname"

这花了我很多时间整理,如果它不适合你,请告诉我。

在进行了大量研究并阅读了大量 Microsoft 文档之后,我能够 运行 在 blazor 之外的不同框架中的一个 individual blazor 组件(在我的案例),

首先 - 我在 Visual Studio 中针对 .net 5.0 初始化了一个新的 Blazor Webassmebly 项目。

为了简单起见,让我们从 blazor bootstrap 应用程序中获取计数器组件。

步骤 - 1 像这样导入要导出为可重用组件的组件 -

第 2 步 - 修改您的 MainLayout.razor 以加载组件

第 3 步 - 这是关键的一步。在您的 Counter 组件中,您应该添加以下代码行,在这里我们将使用 DotNetObjectReference

设置组件的引用

注入 @inherits LayoutComponentBase @inject IJSRuntime js

在您的组件代码部分 -

 private int currentCount = 0;

    private DotNetObjectReference<Counter> jsToDotNetBridgeReference;
    protected override async Task OnInitializedAsync()
    {
        jsToDotNetBridgeReference = DotNetObjectReference.Create(this);
        await js.InvokeVoidAsync("SetDotNetReference", jsToDotNetBridgeReference);
    }


    [JSInvokable]
    private void IncrementCount()
    {
        currentCount++;
    }

[JSInvokable] 标识符帮助 dotnet 将此函数识别为从 JavaScript.

调用的函数

Step - 4 修改Program.cs和index.html

修改你的 index.html 并更改你的 div id 以反击

接下来修改您的 program.cs 以在 html 中查找计数器 ID。

第 5 步 - 将 dotnetreference 设置为 javascript window 对象

在您的 index.html 脚本标签下添加以下脚本 -

window.SetDotNetReference = function (pDotNetReference) {
        DotNetReference = pDotNetReference;
    }

这就是您在 blazor webassembly 应用程序上要做的所有事情。

第 6 步 - 将 Blazor 应用程序发布到文件夹。我现在使用默认位置。发布后您将看到以下文件和文件夹,我们对 _framework 文件夹中的大部分感兴趣。

发布完成后,像这样将 _framework 文件夹复制到其他应用程序的根目录 -

第 7 步 - 转到您想要的框架,现在我将使用 knockout mvc 应用程序。

在您的 layout.cshtml 文件中,像这样添加对 blazor 库的引用

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

保持 autostart = false 是确保 blazor 组件在不需要时不加载的好方法。

第 8 步 - 创建 BlazorInterop.js

在您的框架项目中创建一个 js 文件,我喜欢将其命名为 BlazorInterop.js(可以是任何名称)然后在您的 layout.cshtml 中引用它

<script src="~/BlazorInterop.js?" type="text/javascript"></script>

在 BlazorInterop.js 中,您将编写要从 blazor 应用程序中的主机应用程序执行的函数。像这样-

       IncrementCounter = function () {
    Blazor.start().then(()=> {
        DotNetReference.invokeMethodAsync('IncrementCounter');
    })
   
}

第 9 步 - 使用 id=counter

在 layput.cshtml 中创建 div

创建一个带有 id=counter 的 div,这将有助于 blazor appp 识别 div 它应该像这样放置组件的地方 -

 <div id="counter"> 

    </div>
    <button type="button" onClick="IncrementCounter"> Increment Counter </button>

为了在页面加载时立即看到 blazor 组件 autostart=true 否则,如果您想按需加载组件,我在主机应用程序中添加了一个按钮以显示您可以调用 blazor加载组件后,如果你想运行。

在您的 blazor 中 interop.js Blazor.start 将启动 blazor 应用程序,然后 DotNetReference.invokeMethodAsync 将触发 blazor 中的函数并且计数器应该递增。

第 10 步 - 在 web.config 的 mvc 应用程序中添加 mime 类型以像这样提供静态内容 -

 <staticContent>
      <remove fileExtension=".wasm"/>
      <mimeMap fileExtension=".wasm" mimeType="application/wasm"/>
      <remove fileExtension=".dat"/>
      <mimeMap fileExtension=".dat" mimeType="application/dat"/>
      <remove fileExtension=".br"/>
      <mimeMap fileExtension=".br" mimeType="application/br"/>
      <remove fileExtension=".gz"/>
      <mimeMap fileExtension=".gz" mimeType="application/gz"/>
      <remove fileExtension=".blat"/>
      <mimeMap fileExtension=".blat" mimeType="application/blat"/>
      <remove fileExtension=".pdb"/>
      <mimeMap fileExtension=".pdb" mimeType="application/pdb"/>
      <remove fileExtension=".dll"/>
      <mimeMap fileExtension=".dll" mimeType="application/octet-stream"/>
      <remove fileExtension=".json"/>
      <mimeMap fileExtension=".json" mimeType="application/json"/>
    </staticContent>

大功告成! 启动你的淘汰赛应用程序,你将能够看到该组件。

这基本上是我们在 mvc knockout 应用程序中加载 blazor 组件所需要发生的事情,此方法也适用于任何其他框架,但是我不确定是否要添加 mime 类型以在假设框架中提供静态内容像 angulr、react 等,但我相信一定有某种方法。我没有研究过。

可能会 运行 出现一些错误,因此我将留下一些我在整个过程中参考的文档。

从 JS 调用 .Net 方法 https://docs.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-dotnet-from-javascript?view=aspnetcore-6.0

从 .net 调用 JS 方法

https://docs.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-6.0

如何正确使用blazor.start

https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/startup?view=aspnetcore-6.0

这花了我很多时间来整理,这个特定的工作流程对我们很有效,并计划在月底发布产品。

这有助于我们在 Blazor 中为我们的应用程序开发新功能,从而在无需获取新资源的情况下推进新技术。

从 .NET 6 开始可用的一种可能性是通过调用 JSComponentConfigurationExtensions.RegisterForJavaScript.

让 Blazor 组件可用于 JavaScript 的实例化

我也处于一种情况,我想逐步将现有的 JS 应用程序迁移到 Blazor。但是,它是一个 Angular 应用程序。为了评估可能的解决方案,我创建了一个演示迁移项目。看我的BlazorInAngularDemo github project for the code and description and a working demo。但正如已经说过的,它专门针对 Angular。但也许有些想法,尤其是 README 文件中的一些想法,无论如何都可以帮助您。