locked
screen.details.rootContentItem.handleViewDispose not working??? RRS feed

  • Question

  • I tried to put in code to clean up change listeners as suggested at http://social.msdn.microsoft.com/Forums/vstudio/en-US/d509bee9-99f9-446d-ab22-812b7f73e683/cleaning-up-change-listeners-event-handlers-in-html-client?forum=lightswitch but when I put breakpoints in the handleViewDispose function code the debugger won't stop. I would expect it to when leaving the screen or closing the browser. I have a feeling the function is never run. Anybody know anything about this?

    myapp.LicenseKeyAddEdit.created = function (screen) { screen.addChangeListener("inpAppSystem", inpAppSystem_OnChange); screen.addChangeListener("inpLicenseType", inpLicenseType_OnChange); debugger; // Stops here ok

    screen.details.rootContentItem.handleViewDispose(function () { debugger; // Will not stop here screen.removeChangeListener("inpAppSystem", inpAppSystem_OnChange); screen.removeChangeListener("inpLicenseType", inpLicenseType_OnChange); }); .... };



    Bruce

    Wednesday, July 9, 2014 5:44 PM

Answers

  • I think something has changed since Huy shared this nugget about cleaning up listeners.  It seems I cannot get .rootContentItem.handleViewDispose to fire either.  I tried climbing up the contentItem tree until I found one that does execute like so:

    myapp.AddEditContact.created = function (screen) {
        // Write code here.
    
        screen.details.rootContentItem.handleViewDispose(function () {
            //this doesn't exec
            alert("View Dispose1");
        });
        var tabgroup = screen.findContentItem("Tabs")
        tabgroup.handleViewDispose(function () {
            //this doesn't exec
            alert("View Dispose3");
        });
        var details = screen.findContentItem("Details")
        details.handleViewDispose(function () {
            //this does execute
            alert("View Dispose4");
        });
    
    };
     

    "Details" is the first tab on a default AddEdit Screen.  So it looks like you have to use the first tab on the screen. 

    The change is probably due to the major update to screen navigation since Huy wrote about this.  Perhaps the rootContentItem and Tabs group are reused on all screens so the view is never disposed(?)

    HTH,

    Josh

    • Proposed as answer by Paul Van Bladel Thursday, July 10, 2014 10:31 AM
    • Marked as answer by Angie Xu Monday, July 21, 2014 7:51 AM
    Wednesday, July 9, 2014 7:01 PM

All replies

  • I think something has changed since Huy shared this nugget about cleaning up listeners.  It seems I cannot get .rootContentItem.handleViewDispose to fire either.  I tried climbing up the contentItem tree until I found one that does execute like so:

    myapp.AddEditContact.created = function (screen) {
        // Write code here.
    
        screen.details.rootContentItem.handleViewDispose(function () {
            //this doesn't exec
            alert("View Dispose1");
        });
        var tabgroup = screen.findContentItem("Tabs")
        tabgroup.handleViewDispose(function () {
            //this doesn't exec
            alert("View Dispose3");
        });
        var details = screen.findContentItem("Details")
        details.handleViewDispose(function () {
            //this does execute
            alert("View Dispose4");
        });
    
    };
     

    "Details" is the first tab on a default AddEdit Screen.  So it looks like you have to use the first tab on the screen. 

    The change is probably due to the major update to screen navigation since Huy wrote about this.  Perhaps the rootContentItem and Tabs group are reused on all screens so the view is never disposed(?)

    HTH,

    Josh

    • Proposed as answer by Paul Van Bladel Thursday, July 10, 2014 10:31 AM
    • Marked as answer by Angie Xu Monday, July 21, 2014 7:51 AM
    Wednesday, July 9, 2014 7:01 PM
  • Josh,

    100% correct, the interface slightly changed.

    In fact, I'm sometimes wondering why we should ever use ChangeListener functionality. As far as I can see, everything you can do with a changelistener can also be done via the DataBind functionality used in a postRender block. Obviously with the advantage not having to worry about the clean up of the changelistener.

    Do you see any use cases for Changelisteners, or things that can't be done via the DataBind method?

    Thanks.

    paul


    paul van bladel

    Thursday, July 10, 2014 10:36 AM
  • Thanks Paul. 

    You're right, dataBind is better, but the method is available only to contentItems.  I rarely need addChangeListener, but it is useful when you want to listen for changes on objects that are not contentItems or when you want to put the code in method other than a render method (no contentItem):

    visualCollection.addChangeListener("isLoaded",...

    entity.addChangeListener("LastName",...

    Even with most of these cases, I try to use findContentItem with dataBind if possible.

    Josh

    Thursday, July 10, 2014 11:09 AM
  • Of course... not everything is a contentitem.

    Thanks Josh.


    paul van bladel

    Thursday, July 10, 2014 11:58 AM
  • Josh/Paul:

    Thanks for the reply and additional information. Very enlightening.

    Bruce


    Bruce

    Thursday, July 10, 2014 12:15 PM
  • Josh:

    I just found out that it works on an AddEdit screen, but not a browse screen. Sheesh - I wonder if I should just forget about cleaning up change listeners.

    myapp.Subscriptions.created = function (screen) {
        screen.addChangeListener("CurrentAccount", CurrentAccount_OnChange);
    
        var firstTab = screen.findContentItem("GroupMain");
        firstTab.handleViewDispose(function () {
            // This never gets executed.
            screen.removeChangeListener("CurrentAccount", CurrentAccount_OnChange);
        });
        ...
    }


    Bruce

    Thursday, July 10, 2014 12:56 PM
  • Bruce,

    It seems you're right.  Not handleViewDispose on  a second tab doesn't even fire.  I'd suggest using dataBind whenever you can get a contentItem.  I believe you can do what you want in .created method like so:

    myapp.Subscriptions.created = function (screen) {
        screen.findContentItem("CurrentAccount").dataBind("value", CurrentAccount_OnChange);
    
        ...
    }

    HTH,

    Josh

    Thursday, July 10, 2014 5:03 PM
  • Josh:

    Thanks for the reply. I'm only using addChangeListener for non-control binding based on previous recommendations.

    Bruce


    Bruce

    Thursday, July 10, 2014 6:15 PM
  • Hi,

    I use changeListeners for screen properties that are not contentItems and in some other cases.  I can't use databind because there are no associated controls on the screen.  screen.findContentItem('MyProperty') returns undefined.  In my scenario it can get fairly complex because there is one function that dynamically adds change listeners to all of the screen properties passed to it.  I tried to add a function to handleViewDispose but it is never called.  Does anyone have any more information on when it is actually necessary to dispose change listeners?  It 'feels' like they are being disposed now when the screen is closed.  I am not noticing any problems from leaving them undisposed.  Nevertheless, I would like to clean them up if that is the best practice. 

    Wednesday, April 8, 2015 3:55 PM