【发布时间】:2021-08-23 08:54:44
【问题描述】:
我们能否将 Blazor 组件呈现为独立的 DOM 片段,或者以其他方式将其作为标准 Web 组件在普通 HTML/JS 页面中使用?
从 Blazor 架构的角度来看,这可能是一个幼稚的问题。到目前为止,我还不是 Blazor 专家,但我认为它对于遗留 Web 应用程序的增量“棕地”现代化可能是一种有用的技术。我很惊讶这似乎没有得到官方支持。
为了说明,考虑这个简单的 Web 组件示例,它呈现一个自定义元素 <date-info>:
// define a custom web component
customElements.define("date-info", class DateInfo extends HTMLElement {
constructor() {
super();
// create an "open" (vs "closed") shadow DOM,
// i.e., accessible to the outside JavaScript
this.attachShadow({ mode: "open" });
}
async connectedCallback() {
console.log(`${this.constructor.name}.${this.connectedCallback.name} called`);
// get the content from the server,
// this could be a Blazor component markup
try {
const response = await fetch("https://worldtimeapi.org/api/ip");
const data = await response.json();
const content = new Date(data.utc_datetime).toString();
this.shadowRoot.innerHTML = `<span>${content}</span>`;
}
catch(e) {
console.error(e);
const info = document.createTextNode(e.message);
this.shadowRoot.appendChild(info);
}
}
});
<!-- use the web component -->
<p>Current time: <date-info/></p>
现在,我想获取并呈现 Blazor/Server 组件的分离标记,而不是获取 https://worldtimeapi.org/api/ip,例如:
@* this is a Blazor component *@
<p>@(DateTime.Now)</p>
此外,我希望此标记保持功能性和动态性,即此 Blazor 组件的客户端 DOM 事件和服务器端更新,以通过包装 Web 组件的生命周期进一步传播两种方式.
当然可以将其设为 Blazor @page 并将其加载到 iframe 中,但我更希望将其呈现为外部页面 DOM 的一部分。
到目前为止,我遇到了这个:
-
显然,这不是 Blazor 早在 2018 年的设计目标之一: https://github.com/dotnet/aspnetcore/issues/16033.
-
后来 Steve Sanderson 创建了一个(非官方的)库来单独测试 Blazor 组件,理论上可以用来获取独立的 Blazor 组件标记:https://stackoverflow.com/a/60457390/1768303。
到目前为止,这是解决这个问题的最佳方法吗?
【问题讨论】:
-
我不喜欢在同一个前端项目中混合技术。过去有太多不好的经历。很多事情都在 Blazor 的控制之下,特别是在使用 Signalr 更新 UI 的服务器端。我不记得您引用的库,但我认为它应该作为预渲染 HTML 集成工作,将组件的管理留在 Blazor 电路外部。查看chrissainty.com/…,了解现有 MVC 项目中的集成示例。
-
谢谢@NicolaBiada。我也不喜欢这种混合,但有些项目有非常具体的限制,所以这可能是一种进行增量更改的方式。您链接的文章很有用。也许,在部分 ASP.NET MVC 视图中使用
Html.RenderComponentAsync可以做到这一点。 -
是的,我使用相同的方法在身份服务器部分混合了 blazor 组件和 MVC 视图页面,仍然是 cshtml 格式。
-
@Webreaper,在 Twitter 上 Florian Rappl mentioned 他的项目 Piral 能够做到这一点。我认为:github.com/smapiot/Piral.Blazor
-
添加了一些代码的答案。相同的代码添加到github.com/dotnet/aspnetcore/issues/35551
标签: c# html .net blazor web-component