2009-09-08 5 views
2

J'utilise le soutien Dojo AjaxDojo - dojo.byId() sur une réponse ajax

function handleSubmit(evt, targetUrl, submitForm, updateDiv) { 
      dojo.stopEvent(evt); 
      dojo.xhrPost({ 
       url: targetUrl, 
       handleAs: "text", 
       load: function(response){ 
        updateDiv.innerHTML = response; 
        wireEvents(); 
        return response; 
        }, 
       form: submitForm, 
       error: function(response, ioArgs) { 
        console.error("HTTP status code: ", ioArgs.xhr.status); 
        return response; 
       }    
      }); 
     } 

La réponse du serveur contient plus de données que ce que je dois. Je voudrais être en mesure de remplacer cette

load: function(response){ 
    updateDiv.innerHTML = response; 
    wireEvents(); 
    return response; 
}, 

dans quelque chose comme

load: function(response){ 
     updateDiv.innerHTML = dojo.byId('elemToExtract', response); 
     wireEvents(); 
     return response; 
    }, 

J'ai de mettre à jour ma page avec une partie de la réponse ajax. J'ai besoin de la possibilité d'utiliser le sélecteur dojo.byId sur la réponse (en utilisant la réponse comme une racine de contexte ou quelque chose comme je l'ai trouvé dans jQuery).

Savez-vous comment puis-je y parvenir?

Merci

Répondre

0

Max & série ..Merci beaucoup! A la fin, la solution est basée sur ce que Massimiliano a suggéré. Je l'ai adapté au dojo 1.2.3 (car il manque également la fonction dojo.empty()). "results [0] .innerHTML" doit être appelé pour extraire la dom de la variable dojo. Puis, sans appeler empty(), je peux remplacer directement le innerHTML de la cible "updateDiv"

Le point clé ici est la capacité de dojo.query() à interroger un arbre passant un domNode comme contexte (désolé. ..Je suis nouveau au dojo). Je ne sais pas pourquoi mais la vérification "if (results.length) {" pose des problèmes sur le runtime. Si je débogue le JS je pense que j'ajoute un peu de retard et ça marche bien. Le problème est en exécution, il semble que la condition est évaluée à false ... Je ne sais pas pourquoi

Merci encore

4

La réponse que vous recevez est du texte pur, tel que défini par le paramètre handleAs de l'appel ajax. Si vous souhaitez interroger le balisage contenu dans cette réponse avec dojo.byId, vous devez le convertir en HTML analysé, en créant un DOM pour celui-ci. Pour ce faire, vous pouvez créer un élément html temporaire avec la réponse; alors vous pouvez extraire la partie dont vous avez besoin en utilisant dojo.byId.

load: function(response){ 
    var tempDiv = dojo.create('div', {innerHTML: response}); 
    updateDiv.innerHTML = dojo.byId('elemToExtract', tempDiv); 
    wireEvents(); 
    return response; 
}, 

EDIT:

Le ci-dessus contient des erreurs, comme dojo.byId besoin d'un titre comme second argument, et il n'accepte pas un nœud (voir aussi Seth's answer); de plus, il renvoie une instance de noeud qui ne peut pas être affectée à innerHTML. Dans une solution de travail, lorsque vous avez l'élément temporaire, vous devez extraire la partie dont vous avez besoin en utilisant dojo.query. Ensuite, vous pouvez le coller dans le DOM de la vraie page en utilisant dojo.place. Notez que si vous voulez remplacer le contenu précédent, vous devez supprimer tous les enfants du noeud cible avec dojo.empty avant d'utiliser dojo.place.

load: function(response){ 
    var tempDiv = dojo.create('div', {innerHTML: response}); 
    var results = dojo.query('[id=elemToExtract]', tempDiv); 
    if (results.length) { 
     dojo.empty(updateDiv); 
     dojo.place(results[0], updateDiv); 
     wireEvents(); 
    } 
    return response; 
}, 

Notez que les fonctions de dojo.place et dojo.create a été ajouté dans les versions 1.2 et 1.3 respectivement; si vous avez une version antérieure, il peut être remplacé en utilisant l'api DOM:

load: function(response){ 
    var tempDiv = document.createElement('div'); 
    tempDiv.innerHTML = response; 
    var results = dojo.query('[id=elemToExtract]', tempDiv); 
    if (results.length) { 
     dojo.empty(updateDiv); 
     updateDiv.appendChild(result[0]); 
     wireEvents(); 
    } 
    return response; 
}, 
+0

Je vais avoir un regard sur le api doc. On dirait que cette fonction est utilisée dans dojo 1.3.2. J'utilise 1.2.x pour le moment. Je vais jeter un oeil si je peux trouver la fonction relative dans ce vers – mickthompson

+0

Je suis désolé, j'utilise la version 1.3 et je n'ai pas remarqué que créer n'était pas disponible dans les versions précédentes. Quoi qu'il en soit, vous pouvez appliquer la même technique en utilisant l'API DOM de niveau inférieur: vous créez l'élément avec document.createElement ('div') et définissez manuellement la propriété innerHTML, vous devriez alors pouvoir utiliser dojo.byId. Le point convertit le texte brut en html avec DOM. –

+0

Je pense que dojo.create fait plus que simplement créer un élément avec du contenu. Si vous êtes en mesure de passer son résultat en tant que 2ème élémen de byId, dojo.create devrait créer un document que dojo.byId ('elemToExtract', tempDiv) est capable d'analyser. l'API dit que ça doit être un document. Je peux créer un tempDocument avec un élément div avec contenu (innerHTML) = réponse. Le problème est que l'élément que j'ajoute ne contiendra que du texte et qu'il n'a pas de structure analysable par dojo.byId – mickthompson

1

Le problème est que ce dojo.byId attend un document pour le second argument. Un autre problème est que l'ID n'est pas 'connu' tant que l'élément n'est pas placé dans le DOM. (Je peux me tromper sur ce dernier point et/ou cela peut dépendre des navigateurs.Dans les expériences que j'ai effectuées, dojo.byId n'a rien retourné jusqu'à ce que le HTML soit dans le DOM.)

Cela étant dit, vous pourriez accomplir ce que vous voulez en plaçant les données retournées par votre appel ajax dans un élément caché et en utilisant dojo.query dessus.

En supposant que vous avez dans votre HTML:

Ensuite, votre xhrGet ressemble à ceci:

dojo.xhrGet({ 
    url: 'http://jsbin.com/erawu', 
    handleAs: 'text', 
    load: function(data) { 
     var storage = dojo.byId('storage'); 
     storage.innerHTML = data; 
     var want = dojo.query('#iwant', storage)[0]; // or dojo.query(...).forEach(...) 
     if (want) { 
      dojo.byId('hello').innerHTML = want.innerHTML; 
      // depending on what you want 
      // you could also use dojo.place(want, dojo.byId('hello'), 'first') 
     } 
    }, 
    error: function() { 
     console.log(arguments); 
     console.error('ONOES!'); 
    } 
}); 

Voici un working example en utilisant 1.2 dojo.

+0

J'ai également remarqué que l'interrogation avec le sélecteur d'ID échoue jusqu'à ce que vous placiez les éléments dans le DOM réel de la page. Mais vous pouvez essayer de tester l'identifiant avec un sélecteur d'attribut. J'espère que vous le trouverez utile. –

Questions connexes