gpt4 book ai didi

jquery - MVC 3,重用部分 View 和jquery,不与DOM冲突

转载 作者:行者123 更新时间:2023-12-03 22:18:43 24 4
gpt4 key购买 nike

由于我对 MVC 3 和 jquery 还很陌生,我想知道如何解决以下问题的最佳实践解决方案:

我有一个 View ,我使用 jquery ajax 来获取并显示部分 View ,其中包含产品 A 的一些产品详细信息。加载的部分 View 由一堆 html 和 jquery 代码组成,这些代码与定义的 id 相关联部分 View 。

因此,我想重用相同的部分 View 来显示同一 View 上其他产品的详细信息(例如,在弹出对话框中显示产品 B 的详细信息)。每当显示弹出窗口时,新获取的部分 View 将与产品 A 的部分 View 冲突,因为 html 中使用了相同的 id。

Conceptual overview of the case

有没有一种方法可以将 html 和 javascript 封装在部分 View 中,并在多个页面中重复使用它,而不必担心与 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>

Controller -> 操作(显示产品详细信息)

public ActionResult ShowProductDetails(int productId)
{
// Get product from db. and return the partial view

return PartialView("ProductDetails", p);
}

部分 View (产品详细信息)

<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>

问题当分部 View 在 DOM 中加载两次时,div 会发生冲突。

最佳答案

是的。正如您所指出的,不要在 JavaScript 中使用 ids 和 id 选择器。相反,使用类选择器:

例如,在您 View 的标记中:

<div class="container">Partial View content</div>

JS:

var $div = $('div.container');
// do something

为了消除选择具有相同类名的其他标签的可能性,请为部分 View 中的元素分配一个编程名称,该名称仅用作选择器句柄,而不用作 CSS 类。

虽然基于 ID 的查找性能最佳,但在这种情况下,通过基于 [tag+class] 的查找来避免 ID 冲突更有意义。在性能方面,基于 [tag+class] 的查找与 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

但是,如果您知道 child 位于容器 div 内,则可以通过以下方式限制范围:

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', $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 包装器,因为当您加载部分 View 时它不会触发。相反,我重构了 View 的 JS 来调用 setup 函数并传入范围(这将避免选择具有相同类的其他 div):

// Fetch content in the background
$.get(url, input, function (result, response) {
$('#dialogBox').html(result);
SetUpMenuItems($('#dialogBox'));
});

显然,您可以根据您认为适合您的应用的情况进一步修改它,我所展示的是一个想法,而不是最终的解决方案。

  • 如果您再次加载#dialog,它们将覆盖现有标记,因此不会出现重复。
  • 如果您在其他容器中再次加载部分 View ,您可以将其作为上下文传递,这将阻止您访问 #dialogchildren
  • 我为编程类句柄想出了这个任意前缀pv_。这样,您就可以通过查看类名来判断它是用于 CSS 还是用于您的脚本中。

关于jquery - MVC 3,重用部分 View 和jquery,不与DOM冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6966850/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com