在另一个ViewComponent中调用ViewComponent

时间:2017-08-24 14:38:35

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

我目前正在ViewComponent(ViewComponent1)视图中进行编码。在此视图中,我列出了一些项目:Listed items to be clicked

如您所见,通道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 ..任何想法?

1 个答案:

答案 0 :(得分: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>

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

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

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

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

现在你需要做的就是有一些javascript代码在那些标签上监听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>
}