2009-08-25 6 views
2

Est-ce que quelqu'un sait comment résoudre ce problème méchant avec le tri asp.net + asmx + jqGrid. Parce que, pour appeler PageMethods ou services Web asmx de jqGrid, il doit être piraté comme ceci:jqGrid loadonce ne fonctionne pas avec asp.net

datatype: function() { 
        $.ajax({ 
         url: 'Default.aspx/GetPersons', 
         data: "{}", 
         type: "POST", 
         dataFilter: function(data) { 
          var msg = eval('(' + data + ')'); 
          if (msg.hasOwnProperty('d')) 
           return msg.d; 
          else 
           return msg; 
         } 

au lieu de ceci:

datatype: "json" 

À cause de cela, la mise en attribut loadonce true afin de faire mes tri sur le client, ne fonctionne pas et jqGrid appelle le serveur pour chaque événement qui se produit dans la grille.

Des idées?

Thanx Marko

Répondre

2

Je finit par abandonner sur JSON (avec ASP.NET) et juste utilisé XML. Alors tout fonctionne juste. Assurez-vous que le type de retour de votre asmx est XmlDocument

Un bon résumé de tout ce que vous devez faire pour le faire fonctionner (sur le côté client au moins) se trouve sur le l'JQGrid wiki

Regardez leurs échantillon XML et assurez-vous que votre service renvoie un tampon (mieux vaut valider avec Fiddler) qui suit le même schéma.

MISE À JOUR - Quelques exemples de code

Voici le script côté client pour créer la grille

 var mygrid = $("#list").jqGrid({ 
     url: '../../webServices/callsGridService.asmx/getCallsGridDataXML?nd=' + new Date().getTime(), 
     datatype: 'xml', 
     mtype: 'POST', 
     contentType: "text/xml", 
     colNames: ['Call ID', 'Date/Time', 'Duration'], 
     colModel: [ 
     { name: 'callId', index: 'callId', align: "right", key: true }, 
    { name: 'callTime', index: 'callTime', sorttype: 'date' }, 
     { name: 'duration', index: 'duration', align: "right" } 
    ], 
     pager: $('#pager'), 
     rowNum: 10, 
     rowList: [10, 25, 50, 100], 
     sortname: 'callTime', 
     viewrecords: true, 
     sortorder: "desc", 
     height: "100%", 
     multiselect: true, 
     rownumbers: true, 
     gridview: true, 
     autowidth: true, 
     caption: "Calls" 
    }) 

Et voici le code de service (VB.NET):

Public Function getCallsGridDataXML() As XmlDocument 
    Dim xmlRet As New XmlDocument 
    Dim ret As New StringBuilder 

    m_pageNum = CInt(HttpContext.Current.Request.Form.Item("page")) 
    If m_pageNum = Nothing OrElse m_pageNum = 0 Then 
     m_pageNum = 1 
    End If 
    m_pageSize = CInt(HttpContext.Current.Request.Form.Item("rows")) 
    If m_pageSize = Nothing OrElse m_pageSize = 0 Then 
     m_pageSize = 10 
    End If 
    m_sortItem = CStr(HttpContext.Current.Request.Form.Item("sidx")) 
    m_sortOrder = CStr(HttpContext.Current.Request.Form.Item("sord")) 

    Dim dt As DataTable 
    dt = Session(SESSION_CALLS_GRID_DATA) 

    Dim myView As DataView = dt.DefaultView 
    If m_sortItem IsNot Nothing AndAlso m_sortOrder IsNot Nothing Then 
     myView.Sort = m_sortItem & " " & m_sortOrder 
    End If 

    ret.Append("<?xml version='1.0' encoding='utf-8'?>") 
    ret.Append("<rows>") 
    ret.Append("<page>" & m_pageNum & "</page>") 
    ret.Append("<total>" & Math.Floor(dt.Rows.Count/m_pageSize) & "</total>") 
    ret.Append("<records>" & dt.Rows.Count & "</records>") 

    For i As Integer = (m_pageNum - 1) * m_pageSize To Math.Min(dt.Rows.Count - 1, m_pageNum * m_pageSize - 1) 
     ret.Append("<row>") 
     Dim cellCount As Integer = 0 

     ret.Append("<cell>" & Server.HtmlEncode(myView(i)("callId")) & "</cell>") 
     ret.Append("<cell>" & Server.HtmlEncode(myView(i)("callTime")) & "</cell>") 
     ret.Append("<cell>" & Server.HtmlEncode(myView(i)("duration")) & "</cell>") 

     ret.Append("</row>") 
    Next 

    ret.Append("</rows>") 
    xmlRet.LoadXml(ret.ToString) 
    Return xmlRet 
    End Function 

Vous peut voir que je construis le XML comme une chaîne et ensuite le charger dans le XMLDocumennt. Je ne peux pas dire que je sais que c'est la meilleure façon. Vous pouvez créer le DOM XML directement sur le document.

+0

hmm, belle astuce :) Je voudrais essayer xml-way pour sûr ... merci – Marko

+0

pourriez-vous s'il vous plaît poster une partie de votre code lorsque vous utilisez xml ... thanx – Marko

2

Thanx beaucoup Harlev ... aussi pour les autres une astuce, vous pouvez définir la grille à travailler sur le client avec

type de données: l'attribut 'clientside'

. Je ne l'ai pas trouvé au début parce qu'il n'est pas listé dans la documentation en ligne mais c'est dans la documentation pdf que vous pouvez télécharger depuis here.

Vive

+0

oui même si le PDF n'est pas aussi haut à ce jour, il a beaucoup plus d'informations! –

7

Il est un peu en retard, mais voici une (la?) Solution super facile pour toute solution d'asile futurs:

gridComplete: function(){ 
    $("#yourGridID").setGridParam({datatype: 'local'}); 
} 

Voilà. J'utilise 3.7.2, je ne peux pas parler pour d'autres versions. Le problème (apparemment) provient de 'loadonce' fonctionnant seulement avec les valeurs de type de données prédéfinies, ce qu'une fonction n'est pas. Je croire les autres valeurs intégrées fonctionneront également, mais «local» est logique.

+0

Merci! J'ai le type de données en tant que fonction. Définir le type de données: local à gridcomplete fonctionne pour moi! – rsmoorthy

+0

@Groxx: Cela fonctionne pour moi mais seulement pour une colonne: S. Pourriez-vous savoir pourquoi? – DavidS

+0

@DavidS: Il trie seulement pour une colonne? Pas certain. Je peux regarder un peu plus loin, si vous fournissez un peu plus d'informations: est-ce toujours la même colonne? Dans la même position? Est-ce que les autres ne font rien ou frappent-ils le serveur? D'autres paramètres éventuellement pertinents? Et quelle version? Le code est désordonné, et la version compte à des moments étranges. – Groxx

0

Pour ceux à qui la solution de @ Groxx ne fonctionnait pas (quand je l'ai essayé, le contenu de ma grille disparaissait chaque fois que j'essayais de trier une colonne), essayez la solution de this thread. Cela a fonctionné pour moi. J'utilise jqGrid 4.5.4.

Commencez par définir loadonce : true dans les paramètres de votre grille. Comme expliqué here, cela modifie les paramètres de type de données à 'local' après la fin du chargement des grilles pour la première fois. Ensuite, lorsque vous voulez recharger la grille, le changement datatype retour à json:

$('#your-grid').setGridParam({ datatype : 'json' }).trigger('reloadGrid'); 

Si vous utilisez navGrid vous pouvez revoir votre ajouter, modifier et supprimer des options pour forcer votre grille à recharger comme indiqué dans this answer .