在 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 方法
如何正确使用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 文件中的一些想法,无论如何都可以帮助您。
我正在做一个迁移项目。我是团队中唯一的 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
创建一个带有 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 方法
如何正确使用blazor.start
https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/startup?view=aspnetcore-6.0
这花了我很多时间来整理,这个特定的工作流程对我们很有效,并计划在月底发布产品。
这有助于我们在 Blazor 中为我们的应用程序开发新功能,从而在无需获取新资源的情况下推进新技术。
从 .NET 6 开始可用的一种可能性是通过调用 JSComponentConfigurationExtensions.RegisterForJavaScript
.
我也处于一种情况,我想逐步将现有的 JS 应用程序迁移到 Blazor。但是,它是一个 Angular 应用程序。为了评估可能的解决方案,我创建了一个演示迁移项目。看我的BlazorInAngularDemo github project for the code and description and a working demo。但正如已经说过的,它专门针对 Angular。但也许有些想法,尤其是 README 文件中的一些想法,无论如何都可以帮助您。