Colin, I am so grateful for your help. I am now checking out your modified code,and your suggestions on coding neatly are very nice,i'll pay attention to my code from now on.:> Thx again and best wishes.
On 4月3日, 下午8时46分, Colin Mollenhour <[EMAIL PROTECTED]> wrote: > Vin, the changes I made should get it working, but honestly the code from > that article could be rewritten much more neatly... > See the modified code here:http://pastie.caboo.se/51339 > In the future, please use pastie for anything large blocks of code like this > and use spaces rather than tabs, that just makes it so much easier to read.. > So, basically what I did was structure the code so that the "topics" array is > not accessed until I can guarantee that it has been populated. I think what > you are missing is that the Ajax.Request call does not "block" further > execution of the code that it was called from, so any code that follows the > Ajax.Request call is going to get called immediately, which will be before > the onWhatever callbacks get called. > I also removed some unnecessary variables and closures. I would recommend > also that you put this code into an object or class, like > var Topics = { > topics: [], > init: function(){...}, > loadTopics: function(){...}, > displayTopicsList: function(){...} > }; > Event.observe(window,'load',Topics.init); > This would help you avoid namespace issues, like using variables named > "topics". > Colin > Vin wrote:Thanks so much,colin.:> Please check out Brad Neuberg's sample code > on "how-to-handle- bookmarks-and-back"(location as below),in his example he > use "x dhtml library" and "Sarissa" not prototype.js,but i wanna build his > example with prototype.js,then hence my post for help > above.http://codinginparadise.org/weblog/2005/09/ajax-how-to-handle-bookmarks-and-back.htmlIf > you have free time,i'll be very very happy to receive your suggestions. > After loadTopics(),there's another function displayTopicList(),this function > will use the topics array returned by loadTopics().more code as below: > Event.observe(window,'load',init); var topics=[]; function init(){ > dhtmlHistory.initialize(); if(dhtmlHistory.isFirstLoad()){ > topics=oadTopics(); //alert(topics.length); > historyStorage.put("topics",topics); }else{ > topics=historyStorage.get("topics"); }; displayTopicsList(); var > currentTopic=dhtmlHistory.getCurrentLocation(); displayTopic(currentTopic); > $("menu").observe("click",handleTopicChange); > dhtmlHistory.addListener(handleHistoryEvent); }; function loadTopics(){ var > topicXml; var topicElements; var topicss=new Array(); var option={ > parameters:"", method:"get", onSuccess:function(transport){ > topicXml=transport.responseXML; > topicElements=topicXml.getElementsByTagName("topic"); > topicElements=$A(topicElements); topicElements.each(function(elem){ var > currentTopic={}; currentTopic.id=elem.getAttribute("id"); > currentTopic.title=elem.getAttribute("title"); > currentTopic.src=elem.getAttribute("src"); > currentTopic.isDefault=elem.getAttribute("default"); > if(currentTopic.isDefault==null||currentTopic.isDefault==undefined) { > currentTopic.isDefault=false; }; currentTopic.toString=function(){ return > "[id="+this.id+",title="+this.title+",src="+this.src > +",isDefault="+this.isDefault+"]"; }; topicss.push(currentTopic); }); }, > onFailure:function(transport){ alert("Request Failure..."); } }; var > request=new Ajax.Request("data/topics.xml",option); return topicss; } > function displayTopicsList(){ var menu=$("menu"); topics.each(function(elem){ > var newTopic=document.createElement("a"); newTopic.href=elem.src; > newTopic.title=elem.title; newTopic.setAttribute("topicID",elem.id); > newTopic.innerHTML=elem.title; menu.appendChild(newTopic); }); } On 4月2日, > 下午4时35分, Colin Mollenhour<[EMAIL PROTECTED]>wrote:By default, Ajax requests > are asynchronous, meaning that once Ajax.Request is called, it returns > immediately. Your onSuccess code will be called at some later time when the > server has responded. See:http://prototypejs.org/api/ajax/optionsYou could > try asynchronous: false, but I would recommend restructuring your code to not > require synchronous calls since it will "freeze" the browser while waiting > for the server response. I don't know what you are doing with loadTopics() > once it returns, but there is very rarely if ever a need to do synchronous > calls, you just have to approach the problem differently. If you can't figure > this out, show us more code and maybe we can point you in the right > direction. Lastly, you are not using Class.create() how it was intended at > all.. You could replace it with a simple {}, or if you want some OO > structure, create a real class like so: var Topic = Class.create(); > Topic.prototype = { initialize: function(elem){ this.attributes = $H({ id: > elem.getAttribute("id"), title: elem.getAttribute("title"), src: > elem.getAttribute("src"), isDefault: elem.getAttribute("default") || false > }); }, toString: function(){ return > '['+this.attributes.collect(function(pair){ return pair.key+'='+pair.value; > }).join(',')+']'; } }; Then, inside your loop of topics, simply do this: > topicElements.each(function(elem){ topics.push(new Topic(elem)); }); Colin > Vin wrote:Hi, I wanna return a array object when the ajax request > finished,but it failed.And i just don't know why.Any guidance would be > greatly appreciated.:> Sample code as below: function loadTopics(){ var > topicXml; var topicElements; var topics=[];//the array object that i wanna > return var option={ parameters:"", method:"get", > onSuccess:function(transport){ topicXml=transport.responseXML; > topicElements=topicXml.getElementsByTagName("topics"); > topicElements=$A(topicElements); topicElements.each(function(elem){ var > currentTopic=Class.create(); currentTopic.id=elem.getAttribute("id"); > currentTopic.title=elem.getAttribute("title"); > currentTopic.src=elem.getAttribute("src"); > currentTopic.isDefault=elem.getAttribute("default"); > if(currentTopic.isDefault==null||currentTopic.isDefault==undefined) { > currentTopic.isDefault=false; }; currentTopic.toString=function(){ return > "[id="+this.id+",title="+this.title+",src="+this.src > +",isDefault="+this.isDefault+"]"; }; topics.push(currentTopic); }); > //alert(topics.length)//it does show that the topics array has some items > when the request finished.But,how to return it?? }, > onFailure:function(transport){ alert("Request Failure..."); } }; var > request=new Ajax.Request("Data/topics.xml",option); //return > topics;//puzzling me here!!It failed returning here.The topics.length show 0. > }All i wanna do is:to return my topics array object in the above > function.Where should i put my return clause? I try to definded my topics > array as a global variable,pushing its items through the function above(this > step succeeded) and then reference it in some other function,but what is > strange is that its length property show 0 too. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
