ICEfaces
  1. ICEfaces
  2. ICE-3315

View disposal is not always immediate when closing portlet windows via their close widget

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.7.1
    • Fix Version/s: None
    • Component/s: Bridge, Framework
    • Labels:
      None
    • Environment:
      portal portlet liferay

      Description

      Case http://jira.icefaces.org/browse/ICE-2657 outlines a problem and fix for dynamically closing portlets and properly disposing of the related ICEfaces Views.

      However, while doing some testing, I found that, if I put multiple instances of the same portlet on the same page with the following script added:

              <script id="id1234" type="text/javascript">
                  //this function filters executes the callback function only if the 'e' element is included in the closed portlet
                  //function created to factored into a library
                  function filterEvent(element, callback) {
                      return function(p) {
                          var id = '_' + p.portletId + '_';
                          var parent = element;
                          while (parent) {
                              if (parent.id == id) {
                                  callback();
                                  break;
                              } else {
                                  parent = parent.parentNode;
                              }
                          }
                      }
                  }

                  if (Liferay.Publisher) {
                      var e = 'id1234'.asElement();
                      Liferay.Publisher.subscribe('closePortlet', filterEvent(e, function() {
                          $element(e).findBridge().disposeAndNotify();
                      }));
                  }
              </script>

      closing a portlet doesn't always result in the View being disposed immediately. For example, if I put two copies of the chat portlet on the page (with the script added to the portlet content) and then attempt to close one, it may or may not dispose immediately (seems to depend which one it is - it appears to be the "first" one that was added to the page).

      I put some logging into the View class to print out when an instance was created and when the dispose method was called on the instance. First I added two instance of the portlet to the page. When the page had finished reloading, I saw this.

      View.View: 2
      View.View: 3

      So far so good - two views are created, one for each portlet. When I closed portlet view "2", nothing happened. When I closed portlet view "3", it printed out.

      Disposing of View: 3

      When I reloaded the page (or switched tabs or closed the browser), it immediately printed out:

      Disposing of View: 2

      So it seems that the disposal fired correctly from the client but didn't fully complete on the server for some reason. The good news is that it is not hanging around for the session to expire. Maybe it's related to the fact that both script instances have the same ID in the disposal script. Since we don't have an outputScript component yet (http://jira.icefaces.org/browse/ICE-2827) we may want to recommend a more programmatic solution using an outputText component to write out the script and dynamically ensure that the IDs are distinct. There are some caveats with doing this (see http://jira.icefaces.org/browse/ICE-3159).

        Issue Links

          Activity

          Hide
          Deryk Sinotte added a comment -

          Adjust priority and assign to Mircea

          Show
          Deryk Sinotte added a comment - Adjust priority and assign to Mircea
          Hide
          Mircea Toma added a comment -

          The reason why the views are disposed "randomly" is because the scripts have the same ID. The "delayed" disposal is caused by the page reload which disposes all the views contained in the page.

          Show
          Mircea Toma added a comment - The reason why the views are disposed "randomly" is because the scripts have the same ID. The "delayed" disposal is caused by the page reload which disposes all the views contained in the page.
          Hide
          Mircea Toma added a comment -

          Refactored the code to generate element with unique ID used for searching for the portlet container and its associated bridge instance. Also I changed a bit the script so that its context of evaluation is fully isolated.

          <script type="text/javascript">
          if (Liferay.Publisher) {
          (function() {
          var randomID = 'id' + Math.random();
          document.write('<div id="' + randomID + '"/>');
          var element = randomID.asElement();
          Liferay.Publisher.subscribe('closePortlet', function(p) {
          var id = '' + p.portletId + '';
          while (element) {
          if (element.id == id)

          { $element(element).findBridge().disposeAndNotify(); break; }

          else

          { element = element.parentNode; }

          }
          });
          })();
          }
          </script>

          Show
          Mircea Toma added a comment - Refactored the code to generate element with unique ID used for searching for the portlet container and its associated bridge instance. Also I changed a bit the script so that its context of evaluation is fully isolated. <script type="text/javascript"> if (Liferay.Publisher) { (function() { var randomID = 'id' + Math.random(); document.write('<div id="' + randomID + '"/>'); var element = randomID.asElement(); Liferay.Publisher.subscribe('closePortlet', function(p) { var id = ' ' + p.portletId + ' '; while (element) { if (element.id == id) { $element(element).findBridge().disposeAndNotify(); break; } else { element = element.parentNode; } } }); })(); } </script>
          Hide
          Mircea Toma added a comment -

          Setting up a listener for portlet disposal could be greatly simplified if 'closePortlet' event would be fired before removing the DOM element corresponding to the portlet container:

          <script type="text/javascript">
          if (Liferay.Publisher) {
          Liferay.Publisher.subscribe('closePortlet', function(p)

          { ('_' + p.portletId + '_').asExtendedElement().findBridge().disposeAndNotify(); }

          );
          }
          </script>

          Show
          Mircea Toma added a comment - Setting up a listener for portlet disposal could be greatly simplified if 'closePortlet' event would be fired before removing the DOM element corresponding to the portlet container: <script type="text/javascript"> if (Liferay.Publisher) { Liferay.Publisher.subscribe('closePortlet', function(p) { ('_' + p.portletId + '_').asExtendedElement().findBridge().disposeAndNotify(); } ); } </script>
          Hide
          Mircea Toma added a comment -

          We should notify Liferay guys about the possibility for simplifying the event handling with ICEfaces.

          Show
          Mircea Toma added a comment - We should notify Liferay guys about the possibility for simplifying the event handling with ICEfaces.
          Hide
          Deryk Sinotte added a comment -

          It's not possible to test this new script because of the ICE-3416 which is preventing adding operational <script> sections into the page or portlet.

          Show
          Deryk Sinotte added a comment - It's not possible to test this new script because of the ICE-3416 which is preventing adding operational <script> sections into the page or portlet.

            People

            • Assignee:
              Unassigned
              Reporter:
              Deryk Sinotte
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: