我有一个视图,我使用jquery ajax来获取并显示产品A的一些产品详细信息的部分视图.加载的部分视图包含一堆html和jquery代码,它与局部视图中定义的id相关联.
因此,我想重复使用相同的部分视图来显示同一视图中其他产品的详细信息(例如,在弹出对话框中显示产品B的详细信息).每当显示弹出窗口时,新获取的部分视图将与产品A的部分视图冲突,因为在html中使用相同的id.
有没有办法在部分视图中封装html和javascript,并重复使用几页,而不用担心与ID和内容的任何冲突?
我希望我的问题有道理.谢谢,
/尼玛
更新
这里是一些伪代码,概述了我的问题:
视图
<script type="text/javascript"> $(document).ready(function () { $('.productItems').click(function () { var input = { productId: $(this).attr('data-productID') }; var url = url = '<%: Url.Content("~/ProductDetails/ShowProductDetails") %>'; // Show the modal Box with product details $('#dialogBox').dialog({ title: $(this).attr('data-productTitle') }); // Fetch content in the background $.get(url,input,function (result,response) { $('#dialogBox').html(result); }); }); }); </script> <div id="detailsArea"> <% Html.RenderPartial("ProductDetails",Model.Product); %> </div> <div id="productLinks"> <span class="productItems" data-productID="123">Product B</a> </div> <div id="dialogBox" style="display: none;"></div>
控制器 – >动作(ShowProductDetails)
public ActionResult ShowProductDetails(int productId) { // Get product from db. and return the partial view return PartialView("ProductDetails",p); }
部分视图(ProductDetails)
<script type="text/javascript"> function SetProductTabContent(selectedTab) { $("#productDescriptionContent > div").css('display','none'); switch (selectedTab) { case '#tab-1': $('#productDescriptionText').css('display','block'); break; case '#tab-2': $('#productSpecificationText').css('display','block'); break; } $(document).ready(function () { // Get all the menu items var menuItems = $("#productMenu a"); // Select the first tab as default menuItems.first().addClass("menuItemActive"); // Handle the look of the tabs,when user selects one. menuItems.click(function () { var item = $(this); // Get content for the selected tab SetProductTabContent(item.attr('href')); menuItems.removeClass("menuItemActive"); item.addClass("menuItemActive"); return false; }); }); </script> <div id="productMenu" style=""> <a href="#tab-1"> <div class="menuItemHeader">Menu1</div> </a> <a href="#tab-2"> <div class="menuItemHeader">Menu2 </div> </a> </div> <div id="productDescriptionContent"> <div id="productDescriptionText" style="display: none;"> <%: Model.Product.Description %> </div> <div id="productSpecificationText" style="display: none;"> <%: Model.Product.Description2%> </div> </div>
问题
当部分视图在DOM中加载两次时,div会发生冲突.
解决方法
例如,在你看来的标记:
<div class="container">Partial View content</div>
JS:
var $div = $('div.container'); // do something
为了消除选择具有相同类名称的其他标签的可能性,将部分视图中的元素分配给编程名称,该元素仅用作选择器句柄而不是CSS类.
虽然基于ID的查找是最佳性能明智的,但在这种情况下,通过[tag class]查找可以更有意义地避免id冲突.基于[标签类]的查询在性能方面非常接近id选择器.
此外,您可以通过限制查找范围获得进一步改进:
<div class="container">Partial View content <span class="child">Child content </span></div> var $span = $(span.child') // scope of lookup here is entire document
但是,如果您知道该小孩在容器区域内,则可以通过以下方式限制范围:
var $div = $('div.container').children('span.child'); // or just '.child'
另一个提示是进行一次查找并重新使用它:
// less performant function doSomething() { // do something here $('div.container').css('color','red'); // do other things $('div.container').find('.child'); // do more things $('div.container').click(function() {...}); } // better function doSomething() { var $div = $('div.container'); // do something here $div.css('color','red'); // do other things $div.find('.child'); // do more things $div.click(function() {...}); // or chaining them when appropriate $('div.container').css('color','red').click(function() { ... }); }
更新:重构OP的帖子来演示这个概念:
<script type="text/javascript"> function SetProductTabContent(selectedTab,ctx) { var $container = $("div.pv_productDescriptionContent",ctx); // this will find only the immediate child (as you had shown with '>' selector) $container.children('div').css('display','none'); switch (selectedTab) { case '#tab-1': $('div.pv_productDescriptionText',$container).css('display','block'); // or $container.children('div.pv_productDescriptionText').css('display','block'); break; case '#tab-2': $('div.pv_productSpecificationText','block'); // or $container.children('div.pv_productSpecificationText').css('display','block'); break; } function SetUpMenuItems(ctx) { // Get all the menu items within the passed in context (parent element) var menuItems = $("div.pv_productMenu a",ctx); // Select the first tab as default menuItems.first().addClass("menuItemActive"); // Handle the look of the tabs,when user selects one. menuItems.click(function () { var item = $(this); // Get content for the selected tab SetProductTabContent(item.attr('href'),ctx); menuItems.removeClass("menuItemActive"); item.addClass("menuItemActive"); return false; }); } </script> <div style="" class="pv_productMenu"> <a href="#tab-1"> <div class="menuItemHeader"> Menu1</div> </a><a href="#tab-2"> <div class="menuItemHeader"> Menu2 </div> </a> </div> <div class="pv_productDescriptionContent"> <div class="pv_productDescriptionText" style="display: none;"> <%: Model.Product.Description %> </div> <div class="pv_productSpecificationText" style="display: none;"> <%: Model.Product.Description2%> </div> </div>
注意:我删除了document.ready包装器,因为加载部分视图时不会触发.相反,我重构了你的View的JS来调用setup函数,并且传入范围(这将避免使用同一个类选择其他div):
// Fetch content in the background $.get(url,response) { $('#dialogBox').html(result); SetUpMenuItems($('#dialogBox')); });
显然,您可以根据您认为合适的应用进一步修改这个内容,我所看到的是一个想法,而不是最终的解决方案.
>如果再次加载#dialog,它们将覆盖现有的标记,因此不会有重复.>如果您在其他容器中再次加载部分视图,则可以将其作为上下文传递,这将阻止您访问#dialog的子项>我想出了这个任意前缀pv_的程序化类句柄.这样,您可以看到类名,如果是用于CSS或在脚本中使用.