2015-08-28 89 views
5

我有一个问题,我使用相同的模板呈现页面上的某些内容,并使用相同的模板使用AJAX请求在页面上呈现其他内容。TagBuilder不会在Ajax请求中生成唯一的id属性值

下面的代码呈现局部Razor视图:

@model SearchBoxViewModel 
<div class="smart-search"> 
    @using (Html.BeginForm("Index", "Search", FormMethod.Get, new { @class = "form-horizontal", role = "form" })) 
    { 
     <div class="form-group"> 
      <div class="hidden-xs col-sm-1 col-md-1 col-lg-1 text-right"> 
       @Html.LabelFor(m => m.SearchPhrase, new { @class = "control-label heading" }) 
      </div> 
      <div class="col-xs-8 col-md-9 col-lg-10"> 
       @Html.TextBoxFor(m => m.SearchPhrase, new {@class = "form-control", placeholder = "for products, companies, or therapy areas"}) 
      </div> 
      <div class="col-xs-4 col-sm-3 col-md-2 col-lg-1"> 
       <input type="submit" value="Search" class="btn btn-default"/> 
      </div> 
      <div class="what-to-search hidden-11 col-sm-11 col-sm-offset-1"> 
       <div class="checkbox"> 
        <label> 
         @Html.CheckBoxFor(m => m.WhatToSearch, null, false) 
         @Html.DisplayNameFor(m => m.WhatToSearch) 
        </label> 
       </div> 
      </div> 
     </div> 
    } 
</div> <!-- /.smart-search --> 

下面的代码使得AJAX请求:

$.ajax(anchor.attr("data-overlay-url-action")) 
     .done(function (data) { 
      $("div.overlay").addClass("old-overlay"); 

      $("div.navbar").after(data); 

      $("div.overlay:not(.old-overlay)") 
       .attr("data-overlay-url-action", anchor.attr("data-overlay-url-action")) 
       .hide() 
       .fadeIn(); 

      $("div.old-overlay") 
       .fadeOut() 
       .removeClass("old-overlay"); 

      anchor.addClass("overlay-exists"); 
     }); 

那么你得到的是页面上的相同部分Razor视图输出两次,一次在页面请求期间,一次在AJAX请求期间。

问题是,TextBoxFor,CheckBoxFor等都使用TagBuilder.GenerateId来生成id属性值,但它并没有考虑在可能涉及AJAX的多个请求中生成id的情况。这导致在页面上输出相同的id值,导致JavaScript中断。

以下是输出两倍的HTML(在申请一次,然后在页面中的一个独立部分AJAX请求过程中添加):

<div class="smart-search"> 

<form role="form" method="get" class="form-horizontal" action="/PharmaDotnet/ux/WebReport/Search">  <div class="form-group"> 
      <div class="hidden-xs col-sm-1 col-md-1 col-lg-1 text-right"> 
       <label for="SearchPhrase" class="control-label heading">Search</label> 
      </div> 
      <div class="col-xs-8 col-md-9 col-lg-10"> 
       <input type="text" value="" placeholder="for products, companies, or therapy areas" name="SearchPhrase" id="SearchPhrase" class="form-control"> 
      </div> 
      <div class="col-xs-4 col-sm-3 col-md-2 col-lg-1"> 
       <input type="submit" class="btn btn-default" value="Search"> 
      </div> 
      <div class="what-to-search hidden-11 col-sm-11 col-sm-offset-1"> 
       <div class="checkbox"> 
        <label> 
         <input type="checkbox" value="true" name="WhatToSearch" id="WhatToSearch"> 
         NewsManager Search Only 
        </label> 
       </div> 
      </div> 
     </div> 
</form></div> 

所以SearchPhrase和WhatToSearch ID是重复的。

有没有办法解决这个问题,还是有更好的方法来渲染表单元素来避免这个问题?

回答

2

您可以为项目指定自己的ID,然后就不会出现此ID冲突问题。你有没有尝试手动设置ID:Html.TextBoxFor(... , new { id = "AnythingHere" }),其中的ID可能是一个新鲜的GUID? (请注意,您可能需要添加前缀,因为Guids可以以数字开头

因此,您可以使用以下内容:Guid看起来不好,而且不必要的长。东西短,例如短GUID,DateTime.Ticks,...

@{ 
    var id = "chk_" + Guid.NewGuid().ToString(); 
} 
@Html.CheckBoxFor(..., new { id = id }) 
@Html.LabelFor(..., new { @for = id }) 
+0

我有一些把原来的ID,并附加唯一的字符串来结束它,但我希望为一些更聪明,唯一的CheckBoxFor和DisplayNameFor如何知道哪一个与对方相互关联,以便唯一标识符匹配,我甚至可以向不同的渲染引擎开放,因为我一直在寻找Razor的限制。 –

+0

我没有看到自己指定ID的问题。我在这里并没有真正看到一个限制。如果您想为这个问题提供一个复杂的解决方案,您可以尝试唯一标识每个请求,并根据该请求为所有元素添加后缀。但要做到这一点,你需要自己写助手。 – Tamas

+0

问题更多地与保持代码清洁有关,因为这将是一种常见现象,我宁愿不必在每个部分剃须刀视图的顶部包括我认为是破解的东西。 –