locked
Changing dataSource for ListView: works only for 1 change, then blank!

    Question

  • Ok so here is a weird one!  This simple code works great to change out the dataSource on my ListView control:

    My ListView HTML:

     <div id="hatContainer" style="height:170px;"  data-win-control="WinJS.UI.ListView"
    data-win-options="
    {itemDataSource:HatDataExample.hats.dataSource,
    itemTemplate:select('#hatTemplate'), layout:{type:WinJS.UI.GridLayout, maxRows:1}}">
     </div>

    My function to load the EYES instead of HATS:

    function loadEyes() {
    hatContainer.winControl.itemDataSource = EyeDataExample.eyes.dataSource;
    }

    Now if I click the eyesBtn 1 time, it loads the eyes into the ListView control just fine. However, if I click the similar hatsBtn which has an identical function, or try clicking the eyesBtn again, my ListView goes blank!

    Always something eh?

    Anybody encounter this problem before?


    Friday, September 28, 2012 7:48 PM

All replies

  • Hmm some more weird behavior!

    I tried adding this line in various places for both the hats and eyes:

    EyeDataExample.eyes.notifyReload()

    This seems to help some - if I use this reload, then push the new items button TWICE - the list always loads. Not once, but TWICE is the only way I get things reloading. So somehow I need to mimic whatever that 2nd click is doing programmatically...(I tried the hack of just creating another identical function called at the end of the button click, but that was a bomb :)

    Friday, September 28, 2012 8:19 PM
  • Well some progress, although this hacked up solution is surely not a very good one!  I think this is a timing issue; and tested by using Greensocks JS Tween engine (which is awesome and very easy to use...) - to add a delayedCall, which just calls the same function twice - kind of like a another button click. Sure enough, if I set the value to just .2 seconds, the list fails to load. At .5 seconds, it loads every time. But since you can't know the speed things will be going on in the real world with so many devices - that means this is a pretty terrible solution, but at least it shows me where the problem may be.  Here's my hackery!

    function reloadHats() {
    HatDataExample.hats.notifyReload()
    }

    function reloadEyes() {
    EyeDataExample.eyes.notifyReload()
    }

    function loadEyes() {
    reloadHats();
    hatContainer.winControl.itemDataSource = EyeDataExample.eyes.dataSource;
    TweenMax.delayedCall(.5,loadEyesAgain);
    }

    function loadHats() {
    reloadEyes();
    hatContainer.winControl.itemDataSource = HatDataExample.hats.dataSource;
    hatContainer.winControl.itemDataSource = HatDataExample.hats.dataSource;
    TweenMax.delayedCall(.5,loadHatsAgain);
    }

    function loadEyesAgain() {
    reloadHats();
    hatContainer.winControl.itemDataSource = EyeDataExample.eyes.dataSource;
    }

    function loadHatsAgain() {
    reloadEyes();
    hatContainer.winControl.itemDataSource = HatDataExample.hats.dataSource;
    }


    Friday, September 28, 2012 9:07 PM
  • Seems I don't need to load it twice, only to delay the call to the .5 seconds after clearing the other list. This works too, without the flickering out of the old list:

    function reloadHats() {
    HatDataExample.hats.notifyReload()
    }

    function reloadEyes() {
    EyeDataExample.eyes.notifyReload()
    }

    function loadEyes() {
    reloadHats();
    TweenMax.delayedCall(.5,loadEyesAgain);
    }

    function loadHats() {
    reloadEyes();
    TweenMax.delayedCall(.5,loadHatsAgain);
    }

    function loadEyesAgain() {
    reloadHats();
    hatContainer.winControl.itemDataSource = EyeDataExample.eyes.dataSource;
    }

    function loadHatsAgain() {
    reloadEyes();
    hatContainer.winControl.itemDataSource = HatDataExample.hats.dataSource;
    }

    Friday, September 28, 2012 9:11 PM
  • Nah scratch that, doesn't actually work. So far only the first super hacked up solution makes my lists switch out w/out fail.
    Friday, September 28, 2012 9:14 PM
  • Hi Stacey,

    I just ran into this issue and for the life of me I couldn't figure it out. I knew it had to do with binding because the data was coming back fine.

    What seems to work for me is very similar to your hacked solution, but easier! Just call `notifyReload` after you set the `itemDataSource`. To me, this makes sense because we set it, then force the ListView to update.

    service.refreshAsync(force).then(
        function(data) {
            myListView.itemDataSource = data.dataSource;
            
            // Force list view to update itself, otherwise
            // there will be timing issues and it may come up blank
            data.notifyReload();
        }
    );

    Testing on my Surface which showcases this bug pretty well (but even my desktop PC would too sometimes), and I haven't had it turn blank on me yet. My refresh times are between 1400ms and 3500ms (web service).

    I only had to worry about this because I coudn't figure out a good way to batch changes using only a List (you can do it if you make a custom data source, but that's overkill for me).


    Kamran A


    • Edited by subkamran Sunday, December 02, 2012 8:16 AM
    Sunday, December 02, 2012 8:16 AM