MVC 3,部分意见和jQuery重用,没有发生冲突的DOM [英] MVC 3, reuse of partial views and jquery, without conflicting the DOM
问题描述
因为我还是新的MVC 3和jQuery,我想知道一个最佳实践解决方案,以下是如何可以解决的:
As i am still new to MVC 3 and jquery, i would like to know a best practice solution to how the following can be solved:
我有一个观点,在这里我使用jQuery AJAX来获取和显示与一些产品的细节产品A的局部视图加载的局部视图包含了一堆的HTML和jQuery code,这是联系在一起的的定义的局部视图中的ID。
I have a view, where I use jquery ajax to fetch and display a partial view with some product details for product A. The loaded partial view consist of a bunch of html and jquery code, which is tied to the defined id's within the partial view.
因此,我想重复使用相同的局部视图显示在同一视图(在弹出的对话框显示例如产品B的详细信息)与其他产品的详细信息。每当所示的弹出窗口,新获取的局部视图将与产品A的部分观点相冲突,因为同一ID是在HTML中使用。
Thus, i would like to reuse the same partial view to show details from other products on the same View (e.g. show product B details in a pop-up dialog). Whenever the pop-up is shown, the newly fetched partial view will conflict with the partial view for product A, as the same id's are used in the html.
有没有办法来封装在局部视图的HTML和JavaScript,并重新使用它几页没有关于使用的ID和东西任何冲突的担心?
Is there a way to encapsulate the html and javascript in the partial view, and reuse it several pages without worry about any conflicts with ID's and stuff?
我希望我的问题是有道理的。谢谢,
I hope my question makes sense. Thanks,
/尼玛
更新时间:
下面是一些伪code,勾勒我的问题:
Here is some pseudo code, outlining my issue:
查看
<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);
}
局部视图(产品详细)
<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两次加载。
ISSUE When the partial view gets loaded twice in the DOM, the divs conflicts.
推荐答案
是的。正如你指出的,不要在你的JavaScript中使用的ID和ID选择。而是使用类选择:
Yes. As you pointed out, do not use ids and id selectors in your JavaScript. Instead use class selectors:
例如,在您看来的标记:
<div class="container">Partial View content</div>
JS:
var $div = $('div.container');
// do something
要消除选择具有相同的类名其他标记的可能性,分配一个纲领性的名字是仅用作选择器手柄,而不是作为一个CSS类的局部视图中的元素。
To eliminate possibility of selecting other tags with same class name, assign a programmatic name the elements in partial view which is used only as a selector handle and not as a CSS class.
虽然基于ID查找是最佳的性能明智的,在这种情况下,它更有意义的[标签+级]根据查找去避免ID冲突。 [标签+级]根据查找自带pretty接近ID选择在性能方面。
While ID based lookup is the best performance wise, in this case, it makes more sense to go by the [tag+class] based lookup to avoid id conflicts. [tag+class] based lookup comes pretty close to id selectors in terms of performance.
此外,您还可以通过限制查找范围得到进一步的改进:
Also, you can gain further improvement by limiting the lookup scope:
<div class="container">Partial View content <span class="child">Child content </span></div>
var $span = $(span.child') // scope of lookup here is entire document
但是,如果你知道孩子
是容器div里面,可以说限制范围:
However, if you know that child
is inside container div, you can limit the scope by saying:
var $div = $('div.container').children('span.child'); // or just '.child'
另一个技巧是做查找一次,重复使用它:
Another tip is to do the lookup once and reuse it:
// 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的帖子试玩概念:
Update: Refactoring OP's post to demo the concept:
<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', $container).css('display', '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
包装将不火。相反,我重构视图的JS调用设置功能,并通过在范围之内(这将避免选择与同级别其他的div):
Note: I removed document.ready
wrapper since that will not fire when you load the partial view. Instead, I refactored your View's JS to call the setup function and also pass in the scope (which will avoid selecting other divs with same class):
// Fetch content in the background
$.get(url, input, function (result, response) {
$('#dialogBox').html(result);
SetUpMenuItems($('#dialogBox'));
});
显然,你可以进一步修改成你认为合适你的应用程序,我已经证明是一个想法,而不是最终的解决方案。
Obviously, you can modify this further as you deem fit in your app, what I've shown is an idea and not the final solution.
- 如果您加载
#dialog
再次,他们将覆盖现有的标记,因此不会有重复。 - 如果您在其他容器中再次加载局部视图,可以传递的情况下,这将prevent您访问<$ C的
孩子
$ C> #dialog - 我想出了这个任意preFIX
光伏_
用于编程类处理。这样,你可以告诉看它是否对CSS或在脚本中使用的类名。
- If you load
#dialog
again, they will overwrite existing markup, hence there won't be duplicate. - If you load the partial view again in some other container, you can pass that as the context and that will prevent you accessing the
children
of#dialog
- I came up with this arbitrary prefix
pv_
for programmatic class handles. That way, you can tell looking at the class name if it is for CSS or for use in your script.
这篇关于MVC 3,部分意见和jQuery重用,没有发生冲突的DOM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!