2015-08-28 9 views
5

Mam problem, w którym używam tego samego szablonu do renderowania niektórych treści na stronie, a ten sam szablon jest używany do renderowania dodatkowej zawartości strony za pomocą żądania AJAX.TagBuilder nie generuje unqiue wartości atrybutu id w żądaniach ajaxowych

Poniższy kod renderuje częściowy widok maszynki:

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

Poniższy kod sprawia, że ​​żądania 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"); 
     }); 

Więc co masz jest taka sama częściowe wyjście widok maszynki do golenia na stronie dwa razy , raz podczas żądania strony i raz podczas żądania AJAX.

Problem polega na tym, że TextBoxFor, CheckBoxFor itd. Używają TagBuilder.GenerateId do generowania wartości atrybutu identyfikatora, ale nie uwzględniają generowania identyfikatorów w wielu żądaniach, w których może być zaangażowany AJAX. Powoduje to, że ta sama wartość id jest wyświetlana na stronie, powodując przerwanie JavaScript.

Poniżej znajduje się HTML, który jest odtwarzany dwukrotnie (raz w trakcie wniosek, a następnie dodano w oddzielnej części strony podczas żądania 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> 

Więc SearchPhrase i WhatToSearch ID są duplikowane.

Czy istnieje sposób obejścia tego problemu lub czy istnieje lepszy sposób renderowania elementów formularza w celu uniknięcia tego problemu?

Odpowiedz

2

Można określić swój własny identyfikator dla pozycji, a następnie nie wystąpi problem kolizji ID. Czy próbowałeś ręcznie ustawić identyfikator: Html.TextBoxFor(... , new { id = "AnythingHere" }), gdzie identyfikatorem może być świeżo wygenerowany Guid? (Zauważ, że prawdopodobnie będziesz musiał dodać prefiks, ponieważ Guids może zaczynać się od numeru:

Możesz używać następujących rzeczy: Guid nie wygląda dobrze i jest niepotrzebnie długi. coś krótszego, jak krótkim GUID DateTime.Ticks ...

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

mam coś, co zaczyna oryginalny identyfikator i dołącza unikalny ciąg do końca to, ale miałem nadzieję na coś nieco bardziej sprytny. Jedyną problem z czymś nieco bardziej sprytnym to, w jaki sposób będzie CheckBoxFor i DisplayNameDla dwóch powiązanych ze sobą, aby dopasować unikalny identyfikator, jestem nawet otwarty na inny silnik renderujący, który robi to, ponieważ cały czas znajduję ograniczenia w Razor . –

+0

Nie widzę nic złego w samodzielnym określaniu identyfikatora. Naprawdę nie widzę tutaj ograniczenia. Jeśli potrzebujesz kompleksowego rozwiązania tego problemu, możesz spróbować zidentyfikować każde żądanie w sposób unikalny i na tej podstawie możesz dodać przyrostek do wszystkich elementów. Ale aby to zrobić, musisz napisać pomocników samemu. – Tamas

+0

Problem jest bardziej związany z utrzymaniem kodu w czystości, a ponieważ będzie to powszechne zjawisko, nie będę musiał uwzględniać tego, co uważam za hakowanie u góry każdego widoku częściowego brzytwy. –

Powiązane problemy