【问题标题】:Invoking a ViewComponent within another ViewComponent在另一个 ViewComponent 中调用 ViewComponent
【发布时间】:2018-02-02 12:07:31
【问题描述】:

我目前正在ViewComponent (ViewComponent1) 视图中编码。在这个视图中,我列出了一些项目:

如您所见,频道 11、12、13 和 14 是可点击的。每个频道都有一些附加信息(OBIS、avtalsid.. 等)。我要做的是在 ViewComponent1 中调用 ViewComponent2,并根据单击的项目传递一些数据。

我尝试创建另一个名为“Test”的View,并在该View 中调用 ViewComponent2 及其参数,如下所示:

<div class="row">
    <div class="col-md-2 canalstyle">
        <a asp-controller="Customer" asp-action="Test" asp-route-pod="@item.STATION" 
         asp-route-idnr="@item.IDNR" asp-route-kanal="@item.KANAL" asp-route-start="@Model.start"
         asp-route-end="@Model.end"> @Html.DisplayFor(modelItem => item.KANAL)</a> 
    </div>
</div>

这可行,但是这种方法将我从当前的View(ViewComponent 1)重定向。我不想要那个。我希望当前视图从 ViewComponent2 加载附加信息。

我运行 ajax 的函数:

function myFunction() {

 var data = JSON.stringify({
         'idnr': id,
         'start': this.start,
         'end': this.end
});

 $.ajax({
     url: '@Url.Action("Test2","Customer")',
     type: 'GET',
     data: { idnr: id, start: this.start, end: this.end },
     contentType: 'application/json',
     success: handleData(data)
 })
};

function handleData(data) {
    alert(data);
    var url = $(this).attr("href");
    var $target = $(this).closest("div").find(".details");
    $.get(url, function (res) {
        $target.html(res);
    });
    //do some stuff
}

还有我的 Test2 操作:

public async Task<IActionResult> Test2(string idnr, string start, string end)
{
    ServiceClient r2s = new R2S.ServiceClient();
    R2S.Konstant[] kData = r2s.GetKonstantListAsync(new string[] { "IDNR" }, new string[] { idnr}).Result; // mätarnummer in... --> alla konstanter kopplade till denna.

    return ViewComponent("MeterReader2", new { k = kData[0], start = start, end = end });
}

我正在尝试以相同的 DOM 为目标。有什么想法吗?

【问题讨论】:

    标签: javascript c# asp.net-core asp.net-core-viewcomponent


    【解决方案1】:

    您当前的代码正在呈现链接(标签),通常单击链接会执行一个新的 GET 请求,这就是您所看到的,重定向到新的操作方法。

    如果你不想重定向,但想在同一个视图中显示第二个视图组件的结果,你应该使用 ajax。

    例如,如果您想在每个链接下方显示第二个视图组件的结果,您可以为此添加另一个 html 元素。这里我添加了一个空的 div。

    <div class="row">
        <div class="col-md-2 canalstyle">
            <a class="myClass" asp-controller="Customer" asp-action="DetailsVc" 
                                         asp-route-id="@item.Id" > @item.KANAL</a> 
    
             <div class="details"></div>
    
        </div>
    </div>
    

    在这里,我刚刚删除了您在原始问题中的所有路由参数,并仅替换为 on param (id) 。假设您的项目将有一个 Id 属性,它是记录(主键)的唯一 ID,您可以使用它在视图组件中获取实体(从数据库等)以获取详细信息。

    这将生成带有 css 类 myClass 的链接。您可以看到,我使用asp-action 属性值作为“DetailsVc”。我们不能直接使用链接标签助手中的视图组件名称作为属性值来生成href 值。所以我们应该创建一个包装器操作方法,它返回您的视图组件结果,如下所示

    public IActionResult DetailsVc(int id)
    {
        return ViewComponent("DetailsComponent", new { id =id });
    }
    

    假设您的第二个视图组件名称是 DetailsComponent 并且它接受 id 参数。根据需要更新此操作方法和视图组件的参数列表。 (但我建议只传递唯一的 Id 值并再次在服务器代码中获取详细信息)

    现在你所要做的就是有一些javascript代码来监听那些a标签上的click事件并阻止正常行为(重定向)并进行ajax调用,使用ajax调用结果来更新细节单击的链接旁边的 div。

    您可以将此代码放在您的主视图中(或在没有@section 部分的外部js 文件中)

    @section Scripts
    {
        <script>
            $(function() {
    
                $("a.myClass").click(function(e) {
                    e.preventDefault();
                    var url = $(this).attr("href");
                    var $target = $(this).closest("div").find(".details");
                    $.get(url,function(res) {
                            $target.html(res);
                        });
                });
            });
        </script>
    }
    

    【讨论】:

    • 我有另一个后续问题...是否可以通过上述方法传递一些基于 javascript 值的路由值?我有两个带有日期的文本字段,我想将它们传递给同一个操作...
    • 是的。您可以使用所需的任何路由键值来更新 js 代码中的 url 变量。
    • 如果假设我有 javascript 变量 this.start 和 this.end,该 url 变量将如何实现?我使用额外的 2 个路由键值扩展了您的代码:asp-route-start="" asp-route-end=""
    • 如果您在视图中的标签助手中有asp-route-start,它将在他的 url 中。如果您想在 javascript 中添加其他内容,请在 ajax 调用之前将其连接起来。
    • 我们终于解决了。我们在 URL 中添加了开始日期和结束日期,它起作用了。非常感谢!!
    猜你喜欢
    • 2021-06-21
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    相关资源
    最近更新 更多