问题
I wonder if the procedure outlined below for injecting dynamic content is methodically correct. The approach is based on a slightly modified piece of code described in jQM's Dynamic Page Generation doc that does away with a noticeable statement ($.mobile.changePage).
Assume the page consists of 2 virtual pages ("pgActLst" and "pgActDet"). Virtual page "#pgActLst" contains a collection of anchors that point via PKs to various activities over a specific range; "#pgActDet" details activity specifics associated to the selected PK.
My question addresses the usage of $.mobile.changePage("#pgActDet"). It seems that in my case (anchors), inclusion of this statement becomes unnecessary (and actually gives rise to an infinite loop). Note that the code refreshes content correctly. Is the approach outlined below sound or could it bite me in the long run? As far as I can see, step S1 fires before S2.
// S1. Specify the firing event.
$("a", "#divActLst").live("click", function (e) {
.. // Update local storage with selected ActID PK (The PK is retrieved in evt "pagebeforechange").
})
// S2. If the target URL points to "pgActDet", retrieve activity details via a web service and
// dynamically fill up divActDet.
$(document).bind("pagebeforechange", function (e, data) {
// Check if the target url matches "pgActDet"
var url = $.mobile.path.parseUrl(data.toPage), reg = /^#pgActDet/;
if (url.hash.search(reg) == 0) {
.. // Pull PK actID and txt info from local storage.
GetActDet(actID, txt); // Call up web service and refresh details content.
};
)}
// S3. Inject html if web service qry GetActDet() is successful.
function GetActDetOK() {
.. // Fill up divActDet and bind events.
//$.mobile.changePage("#pgActDet"); // Seems unecessary. (Is this ok?).
}
回答1:
The reason you could do away with the changePage statement is that you did not prevented default behavior in your beforepagechange event. When the event is fired, JQM will run your instructions and continue with its normal behaviour, which is the pagechange. This means two things: it might not have waited for your operations to be completed if you have some asynchronous actions taking place (which you do), and it will get you in an infinite loop if you happen to execute a mobile.changePage.
The proper way to handle that would be to add e.preventDefault(); before calling GetActDet, and call changePage once you have retreived/generated your page content.
回答2:
I think, I figured out the problem. For some reason, the click event fired twice. To eliminate this annoyance, I reset the handler via die(). This probably explains why $.mobile.changePage("#pgActDet") was unnecessary.
In rewriting the code, I used the "pagebeforeshow" event to inject dynamic content in the details page. Event "pagebeforechange" remains untouched. The code is adapted from the article: jQuery Mobile - Ajax - Dynamic content - Passing parameters , substituting "pagebeforeshow" for "pageshow". For those interested, an excerpt is shown below.
**Html**
<div id="divActLst" data_Items="0">
..
<a href="javascript:void(0);" data_pgid="#pgActDet" data_actid="?actid=111" rel="external" >
<span>...</span>
</a>
.. ..
</div>
**Code**
$("a", "#divActLst").die().live("click", function (e) {
// Pack relevant info from the clicked link (ie. pgID="#pgActDet", reqActID="?actid=111", actID=111, txt="2012-09-11 08:12...")
var $this = $(this), o = {};
o.reqActID = $this.attr("data_actid"); o.actID = o.reqActID.get("=", 1).toInt();
o.pgID = $this.attr("data_pgid"); o.txt = $this.text().trim();
$("#divActLst").data("act", o); // Save act info in local storage
$.mobile.changePage("#pgActDet" + o.reqActID); // Activate page change
return false;
});
$("#pgActDet").live("pagebeforeshow", function () {
// Inject dynamic content during this event.
var act = $("#divActLst").data("act"); // Get act info from local storage.
GetActDet(act);
});
function GetActDet(act) {
// Request data via ajax. If succesful, jump to GetActDetOK.
var args = '{ActID: ' + act.actID + '}', url = gSvcUrl + "GetDetActivity";
..
}
function GetActDetOK(objAct, act) {
// Format data via template "tplActDet".
var cbeg = "//<![" + "CDATA["; var cend = "//]" + "]>"; // Remove CDATA brackets.
var rslt = tmpl("tplActDet", { dd: objAct }).replace(cbeg, "").replace(cend, "");
var $divDet = $("#divActDet");
$divDet.empty().html(rslt).trigger("create");
..
}
来源:https://stackoverflow.com/questions/12375988/jqm-debating-correct-approach-to-load-dynamic-content