user3211082
user3211082

Reputation: 75

jQuery Mobile's back button seems to pass cached data between pages

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:

  1. click on "Category 1" in info page
  2. details page opens and informs by alert that "Category 1" was selected
  3. click on an item: alert info shows correctly "Category 1"
  4. click on "back" button anf the info page appears again
  5. click on "Category 2" in the info page
  6. details page opens and informs by alert that "Category 2" was selected
  7. click on an item: it shows "Category 1" (instead of "Category 2"

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

Answers (1)

Yuriy Kvartsyanyy
Yuriy Kvartsyanyy

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

Related Questions