web-dev-qa-db-fra.com

Pourquoi la définition de UnobtrusiveJavaScriptEnabled = true empêche ajax de fonctionner?

En faisant un échantillon en utilisant le rasoir MVC3, j'ai écrit:

<p>
    Show me the time in:
    @Ajax.ActionLink("UTC", "GetTime", new { zone = "utc" }, new AjaxOptions { UpdateTargetId = "myResults" })
    @Ajax.ActionLink("BST", "GetTime", new { zone = "bst" }, new AjaxOptions { UpdateTargetId = "myResults" })
    @Ajax.ActionLink("MDT", "GetTime", new { zone = "mdt" }, new AjaxOptions { UpdateTargetId = "myResults" })
</p>
<div id="myResults" style="border: 2px dotted red; padding: .5em;">
    Results will appear here
</div>
<p>
    This page was generated at @DateTime.UtcNow.ToString("h:MM:ss tt") (UTC)
</p>

Aucun de mes appels ajax n'a fonctionné jusqu'à ce que je modifie cette clé dans web.config:

<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

J'ai lu dans cet article: http://weblogs.asp.net/owscott/archive/2010/11/17/mvc-3-ajax-redirecting-instead-of-updating-div.aspx
Mais maintenant, ma validation côté client ne fonctionne plus comme avant.

Ma question est : comment faire fonctionner les validations ajax et côté client en même temps? Que fait le "UnobtrusiveJavaScriptEnabled"? Est-ce un échange entre eux?! J'espère en savoir plus à ce sujet en termes simples.

32
Amr Elgarhy

Dans ASP.NET MVC 3, il y a 2 choses: la validation côté client et le Javascript discret qui sont contrôlés par leurs valeurs correspondantes dans web.config:

<add key="ClientValidationEnabled" value="true" /> 
<add key="UnobtrusiveJavaScriptEnabled" value="true" /> 

La validation côté client est basée sur le jquery.validate.js plugin avec le jquery.validate.unobtrusive.js script de Microsoft. Lorsque vous incluez ces deux scripts dans une vue qui contient un formulaire HTML, la validation côté client sera effectuée en fonction des règles d'annotation de données que vous avez définies sur votre modèle. Lorsque vous regardez le code source HTML généré de la vue, vous remarquerez que les champs de saisie ont HTML5 data-* attributs qui contiennent les règles de validation. Le script de validation discret de Microsoft lirait alors ces règles et configurerait le plugin de validation jquery.

Le javascript discret est différent. Il est basé sur jquery. Lorsque vous utilisez l'un des Ajax.* Assistants HTML tels que Ajax.ActionLink, dans ASP.NET MVC 3, ces assistants émettent également HTML5 data-* attributs sur l'ancre correspondante. Ces attributs sont ensuite interprétés par Microsoft jquery.unobtrusive-ajax.js script que vous devez inclure dans votre page et AJAXify ces liens. Ainsi, par exemple, lorsque vous écrivez:

@Ajax.ActionLink("UTC", "GetTime", new { zone = "utc" }, new AjaxOptions { UpdateTargetId = "myResults" })

cela générerait le code HTML suivant:

<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#myResults" href="/Home/GetTime?zone=utc">UTC</a>

Comme vous pouvez voir maintenant toutes les informations sur la façon d'exécuter la demande AJAX est contenue dans le DOM. Vous pourriez donc avoir un fichier javascript séparé où vous vous abonneriez pour le click événement de ce lien, envoyez une demande AJAX à l'url contenue dans l'attribut href puis en fonction de la valeur de data-ajax-mode l'attribut remplace le html d'un conteneur par l'id contenu dans le data-ajax-update sélecteur d'attribut. Et c'est exactement ce que le jquery.unobtrusive-ajax.js Est-ce que. C'est juste qu'il est dans un fichier séparé et votre balisage et javascript sont indépendants, ce qui n'était pas le cas dans les versions précédentes.

Contrairement à ASP.NET MVC 1 et 2, dans ASP.NET MVC 3, jQuery est le framework javascript par défaut et les assistants HTML sont basés dessus. Tout MicrosoftAjax* les scripts ne sont plus utilisés.

81
Darin Dimitrov

J'ai résolu cela en utilisant ce code:

@using (Ajax.BeginForm("Index2","Home", 
    new AjaxOptions
        {
            UpdateTargetId = "result", 
            HttpMethod = "POST"
        }, 
    new
        {
            onclick = "Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));",
            onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, httpMethod: 'POST', updateTargetId: 'result' });"
        }))
{
    <input type="hidden" name="id" value='1'/>
    <input type="submit" value="OK" />
}

Ajout des lignes:

new
        {
            onclick = "Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));",
            onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, httpMethod: 'POST', updateTargetId: 'result' });"
        }))

Vous ajoutez le même comportement que le Ajax.BeginForm sans perd le comportement javascript.

Je l'ai testé avec MVC4

0
MrMins