Reputation: 75
I become desperate of a problem that seems to be related to the event mechanism in jQuery that probably I did not understand correctly. I hope that somebody can give me a hint what I am doing wrong.
I have a jQuery Mobile 2-pages file: #info-page: shows categories #details-page: shows the details of an item that was clicked in #info-page
If the user clicks on an item in the info-page, I attach the data of the clicked item to the datails-page by "$("#the_details_page_id").data("name_of_date", thedata)". In the "pagebeforeshow" part of the details page I retrieved this data again and created on base of it the new content. So far, so good.
But all gets wrong if I use the "back" button:
In my tiny example, I do this:
I am really confused. If I leave the stopImmediatePropagation calls I can see that the alert info in the last step is invoked twice - one time with "Category 1" then with "Category 2". Does anybody have a clue what I am doing so totally wrong?
Thank you for your help.
Steve
<body>
<script>
var sample = [{
"id": 2,
"name": "Category 1",
"details" : [
{ "id" : 1, "name": "A Detail"},
{ "id" : 2, "name": "Other Detail"}
]
}, {
"id": 2,
"name": "Category 2",
"details" : [ { "id" : 4, "name": "Also a detail"} ]
}
];
// Kategorie-Seite
$(document).on("pageinit", "#info-page", function () {
var li = "";
$.each(sample, function (i, name) {
li += '<li><a href="#" id="' + i + '" class="info-go">' + name.name + '</a></li>';
});
$("#kategorie-list").append(li).promise().done(function () {
$(this).on("click", "a", function (e) {
var category = sample[this.id];
$("#details-page").data("selected_category", category);
$.mobile.changePage("#details-page");
e.stopImmediatePropagation();
e.preventDefault();
});
$(this).listview("refresh");
});
});
// Details-Seite
$(document).on("pagebeforeshow", "#details-page", function () {
var category = $(this).data("selected_category");
alert ("selected category: " + category["name"] ); // correct!!
var details = category["details"];
var li = ""; // init
$.each(details, function( index, value ) {
li += '<li><a href="#" id="' + details[index]["id"] + '" class="info-go">' + value["name"] + '</a></li>';
});
$("#tables-list").empty().append(li).promise().done(function () {
$(this).on("click", ".info-go", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
alert ("Category in loop:" + category["name"]); // wrong!
});
$(this).listview("refresh");
});
});
</script>
<!--first page -->
<div data-role="page" id="info-page">
<div data-role="content">
<ul data-role="listview" id="kategorie-list" data-divider-theme="a" data-inset="true">
<li data-role="list-divider" data-theme="b" data-role="heading">Kategorien</li>
</ul>
</div>
</div>
<!--second page -->
<div data-role="page" id="details-page">
<div data-role="header" data-theme="b"><a href="#" data-rel="back" data-role="button">Zurück</a>
<h1>Details</h1>
</div>
<div data-role="content">
<ul data-role="listview" id="tables-list" data-divider-theme="a" data-inset="true">
<li data-role="list-divider" data-theme="b" data-role="heading">Details</li>
</ul>
</div>
</div>
</body>
Upvotes: 1
Views: 285
Reputation: 2886
The problem here is that #tables-list
element will have two click handlers attached, one during first details-page show, second after second details page show.
You see two alerts because of these two handlers, first one still have reference to variable scope when it was created. In your case variable category for first handler contains information about 'Category 1'. More information about closures available here.
The quickest way to fix would be remove old event handler using off method.
$(this).off("click").on("click", ".info-go", function (e) {
Upvotes: 1