如何将 ViewModel 传递到 .NET Core 3.1 中的 Razor 组件 [英] How to pass ViewModels into Razor Components in .NET Core 3.1

查看:32
本文介绍了如何将 ViewModel 传递到 .NET Core 3.1 中的 Razor 组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含以下内容的 View MyView.cshtml:

@using MyProject.ViewModels@model MyProject.ViewModels.MyViewViewModel<form asp-action="Test" method="Post"><component type="typeof(MyProject.Views.Home.Test)" render-mode="ServerPrerendered"/><input type="submit" value="send"/></表单>

我有包含以下内容的 Razor 组件 Test.razor(使用 Blazor 语法):

@page "/Test"<div class="form-group top-buffer @Visible"><div class="row"><div class="col-2"><label asp-for="TestName" class="control-label"></label>

<div class="col-3"><input asp-for="TestName" class="form-control"/><span asp-validation-for="TestName" class="text-danger"></span>

<button @onclick="Show">Show</button>@代码 {公共字符串可见{获取;放;} = "隐藏";受保护的异步任务 Show(){可见 = "";}}

MyViewViewModel 类看起来像这样:

命名空间 MyProject.ViewModels{公共类 MyViewViewModel{[显示(名称=测试名称:")]公共字符串测试名称 { 获取;放;}}}

到目前为止一切正常.但是,我现在想将此组件用作 Web 表单的一部分,该表单将在提交后发送到控制器.这就是为什么我需要访问和更改我的 ViewModel 'MyViewViewModel' 的属性.不幸的是,我没有在互联网上找到任何关于如何做到这一点的答案.我不能像在视图中那样使用 @model MyProject.ViewModels.MyViewViewModel 因为这会给我一个编译错误.我想知道我是否需要使用@inject,但如果是,我不知道如何...

(本示例中使用的部分:https://jonhilton.net/use-blazor-in-existing-app/)

解决方案

在 Razor 页面中混合 Blazor 时,您可以执行以下操作:

请记住,您正在处理两个不同的生命周期.因此,如果您确实在 Razor 组件内部工作,该组件将更新但不会影响它所在的​​ Razor 页面.因此,将 Razor 组件和页面与表单混合使用会很困难.

更具体地说是 OP.要将数据从 ViewModel 传递到组件,您可以使用以下方法.

@using MyProject.ViewModels@model MyProject.ViewModels.MyViewViewModel<form asp-action="Test" method="Post"><component type="typeof(MyProject.Views.Home.Test)"渲染模式=ServerPrerendered"param-Name="@Model.TestName"/><input type="submit" value="send"/></表单>

Test.razor

HelloWorld

你好@姓名@代码 {[范围]公共字符串名称{获取;放;} = "未定义";}

关于生命周期基本上,当您在 Blazor 中有一个按钮时,它会触发一个事件,导致组件重新呈现.你可以把它想象成一个 iframe 或更新面板.当您在 Razor 页面中有一个按钮时,它会执行一次 HTTP 调用往返并完全重新加载页面.没有适当的事件系统来告诉 Blazor 调用 HTTP 调用往返来刷新 Razor 页面的内容,反之亦然.您只能从 Razor 页面到 Blazor 进行单向数据绑定,认为只写,并且仅在页面加载时.

I have a View MyView.cshtml with the following content:

@using MyProject.ViewModels
@model MyProject.ViewModels.MyViewViewModel

<form asp-action="Test" method="Post">
    <component type="typeof(MyProject.Views.Home.Test)" render-mode="ServerPrerendered" />
    <input type="submit" value="send"/>
</form>

And I have the Razor Component Test.razor with the following content (with Blazor Syntax):

@page "/Test"

<div class="form-group top-buffer @Visible">
    <div class="row">
        <div class="col-2">
            <label asp-for="TestName" class="control-label"></label>
        </div>
        <div class="col-3">
            <input asp-for="TestName" class="form-control" />
            <span asp-validation-for="TestName" class="text-danger"></span>
        </div>
    </div>
</div>

<button @onclick="Show">Show</button>

@code {
    public string Visible { get; set; } = "hidden";

    protected async Task Show()
    {
         Visible = "";
    }
}

The Class MyViewViewModel would look like this:

namespace MyProject.ViewModels
{
    public class MyViewViewModel
    {
        [Display(Name = "Test Name:")]
        public string TestName { get; set; }
    }
}

Works all pretty fine so far. However I now want to use this component as part of a Web form which will be sent to the controller after submission. That's why I need to access and change properties of my ViewModel 'MyViewViewModel'. Unfortunately I did not find any answer in the internet on how to do that. I can't use @model MyProject.ViewModels.MyViewViewModel like in the view because this will give me a compilation error. I wonder if I need to use @inject, but if yes, I don't know how...

(parts are used from this example: https://jonhilton.net/use-blazor-in-existing-app/)

解决方案

When you mix Blazor in a Razor Page, you can do the following:

Please keep in mind that you are dealing with two different life-cycles. So if you do work inside of a Razor Component, the component will update but not effect the Razor Page it is hosted inside of. So mixing Razor Components and Pages with forms would be difficult.

More specifically to the OP. To pass data from your ViewModel to the component you may use the following method.

@using MyProject.ViewModels
@model MyProject.ViewModels.MyViewViewModel

<form asp-action="Test" method="Post">
    <component type="typeof(MyProject.Views.Home.Test)" 
               render-mode="ServerPrerendered" 
               param-Name="@Model.TestName"/>
    <input type="submit" value="send"/>
</form>

Test.razor

<h3>HelloWorld</h3>

Hello @Name

@code {

    [Parameter]
    public string Name { get; set; } = "undefined";

}

About life cycles Basically when you have a button in Blazor, it will trigger an event which causes the component to re-render. You could imagine it like an iframe, or update-panel. When you have a button in a Razor page, it does a HTTP call round trip and reloads the page entirely. There is no event system in place to tell Blazor to invoke an HTTP call round trip to refresh the Razor page's content and vise versa. You can only one-way data-bind from Razor pages to Blazor, think write-only, and only when the page loads.

这篇关于如何将 ViewModel 传递到 .NET Core 3.1 中的 Razor 组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆