在我的MVC视图中,我有以下内容:
<a href="#" tabindex="0" data-toggle="popover" data-trigger="hover" data-container="body" data-html="true" data-content="@Html.Action("Popover","Client")">Simon Jones</a>
这可以按我的意愿工作,加载客户端控制器中 Popover 操作返回的部分视图。但是,我希望它能够以最小的努力,无论客户端的名称出现在应用程序中的哪个位置,这个弹出窗口都会自动添加到足够近的位置。类似的东西:
<a href="#" class="clientPopover">Simon Jones</a>
将Javascript放在单独的文件中,链接到每个页面,如下所示:
$(".clientPopover").popover({
html: true,
container: 'body',
trigger: 'hover',
content: '@Html.Action("Popover","Client")'
})
我意识到我不能在Javascript中使用HTML Helper,就像我在这里写的那样,但是我尝试了很多不同的方法来实现这一点,但没有成功。
关键要求是我可以非常轻松地指定一个元素应该附加一个popover,它在其内容中呈现一个局部视图。我希望在整个应用程序中使用不同的数据项来实现相同的功能,而不仅仅是客户端,所以我的目标是为每个数据项存储弹出窗口的部分视图的位置(例如客户端) ,工作人员,建筑等。)。
修改 我简化了我的要求,使这个问题更容易理解,但我现在意识到这导致了一个答案,它适用于我的简化问题,但不是我的实际问题。有人建议我可以将Popover内容加载到页面上的隐藏元素中,然后根据需要在Popover中显示它。但是,实际上我的页面可能同时显示许多不同的客户端名称(例如在表格中),并且将鼠标悬停在每个名称上将在Popover中显示该客户端的详细信息。我可以使用Ajax每次在填充Popover之前更新我的隐藏元素的内容,但我怀疑这将是非常高效的,并且感觉过于复杂。
我原本希望的是,一旦我想出如何调用Action为一个客户端加载Popover内容,我就能够扩展解决方案以传递客户端的id,以便Popover的数据是动态加载的。我真的认为这比看起来简单得多!
答案 0 :(得分:2)
您可以使用您的链接在服务器端或客户端包装客户端的名称。
在客户端,我会这样做:
/* assume there is a main container with your content that has the class .content */
var html = $('.content').html();
var linkHtml = '<a href="#" class="clientPopover">Simon Jones</a>';
var newHtml = html.replace(/Simon\s+Jones/gi, linkHtml);
$('.content').html(newHtml);
这是一个有效的jsfiddle: http://jsfiddle.net/s9Laumpq/
然而,更聪明的方法是在服务器端执行此操作,因为javascript方式可以打破其他脚本,这些脚本将事件处理程序附加到代码中的某些html元素。在asp.net中,你需要这个函数来做类似的事情: https://msdn.microsoft.com/en-us/library/xwewhkd1%28v=vs.110%29.aspx
关于第二个问题,您可以在主html文件的javascript变量中编写popover-content
var popoverContent = '@Html.Action("Popover","Client")';
并在单独的javascript文件中使用该varialbe
$(".clientPopover").popover({
html: true,
container: 'body',
trigger: 'hover',
content: popoverContent
});
确保在包含javascript文件之前发生变量赋值。
答案 1 :(得分:1)
除非我误解了你的问题 -
我已经完成了类似的工作,为我们网站上许多不同位置显示的几种不同类型的链接编写HTML助手的扩展。因此,我不是在我的视图代码中编写显式锚标记,而是进行如下调用:
@Html.ClientLink(Model.ClientName)
您的HTML Helper扩展程序如下所示:
public static class MvcHtmlLinkExtensions
{
public static HtmlString ClientLink<TModel>(this HtmlHelper<TModel> helper, string clientName)
{
return new HtmlString(String.Format("<a href=\"#\" class=\"clientPopover\">{0}</a>", clientName));
}
}
您对不同类型的链接也会这样做。我们的扩展实际上更复杂,因为它们将ID作为附加参数并将其作为data-clientID属性嵌入到锚中,该属性稍后由javascript提取并嵌入在弹出URL中。这允许显示每个不同客户端的自定义弹出数据。 (类似于Netflix.com在鼠标悬停在标题上时显示电影细节的方式)。
编辑: 我从你对其他答案的评论中看到我误解了你的问题。我相信你误用了popover函数的content参数。该参数采用的字符串是要在内容中呈现的实际HTML,如果每个客户端的字符串相同,我相信Mario A的建议应该有效。但是,如果您需要从按需在服务器上呈现的部分视图加载内容,则需要使用ajax:
content: function () {
var output = '';
$.ajax(
{
url: "@Html.Action("Popover", "Client")"
async: false,
success: function (response) {
output = response;
}
});
return output;
},
注意 - 如果此函数在剃刀视图中呈现,则只能使用Html.Action助手,而不是如果它存在于静态js文件中。如果是后者,则需要对提供HTML的操作的路径进行硬编码。
进一步编辑 - 我现在看到你 想要预加载部分视图的内容。要做到这一点,我认为最干净的方法是在隐藏的div中将该部分视图呈现在该页面的另一部分中,
<div id="popover_content" style="display:none">
@Html.Action("Popover", "Client")
</div>
然后popover脚本会将popover内容设置为该div中的html:
content: function() {
return $('#popover_content').html();
另一个编辑,回答修改后的问题: 我认为我最终解决方案的变体可行。您可以加载使用客户端ID唯一命名的n个隐藏内容div,并将客户端ID存储在每个链接的data-attribute中。然后你的popover脚本只找到具有该属性的所有锚点,并使用该属性的值调用每个锚点的popover,以找到要加载的内容。
我在这里创建了一个有效的jsfiddle: http://jsfiddle.net/01w8pvkv/
根据您计划在单个页面上加载的客户端数量以及每个div中将包含多少内容,您可能需要考虑从Ajax中提取数据。