locked
Updating datasource has no effect on listview

    Question

  • I have a background task, that imports files and publishes imported files via

    WinJS.Application.queueEvent({type: 'file/import', item: fileItem})

    The view registered an eventListener

    list = new WinJS.Binding.List
    app.addEventListener('file/import', function(event) {
      list.dataSource.insertAtEnd(null, event.item);
      list.dataSource.invalidateAll();
    });

    However, the listview is not updated. Do I have to relayout the listview?

    What is the general recommendation for updating listviews from a background operation?

    edit: I changed list.dataSource.invalidateAll to listview.refresh() which will somehow update the listview.

    But my understanding was that changing the datasource alone will be reflected in the bound listview.


    • Edited by phil_ke Tuesday, February 7, 2012 6:25 PM
    Tuesday, February 7, 2012 6:10 PM

Answers

  •    

    HTML Setup:

    <divid="ListTemplate"data-win-control="WinJS.Binding.Template"style="display: none">


       

    <divclass="win-listview-mediumListIconTextTemplate">


       

    <imgclass="win-listview-mediumListIconTextTemplateImage"src="images/book.png"/>


       

    <divclass="win-listview-mediumListIconTextTemplateLargeText win-itemText"data-win-bind="innerText: title WinJS.Binding.oneTime"></div>


       

    </div>


       

    </div>  


       

    <divid="BooksListView"data-win-control="WinJS.UI.ListView"data-win-options="{dataSource: MyBooksDB, itemRenderer: ListTemplate, selectionMode: 'none', crossSlide: 'none', layout: {type: WinJS.UI.ListLayout} }">

    JavaScript Updater:

            thisListView

    =WinJS.UI.getControl(document.getElementById("BooksListView"));


            thisListView

    .dataSource =MyBooksDB;

    Building My database is done by a JSON array which I have by default in my app. But add to by pulling .xml from a server. But the most important thing to remember is that most of Win.JS is asynchronise. So our apps are not hanging on a callback. Just make sure you have a data array populated then point your dataSource to it.

    Hope this helps...

    • Edited by webdatadesigngroup Wednesday, February 8, 2012 7:34 AM
    • Marked as answer by Bob_Bao Wednesday, March 7, 2012 6:58 AM
    Wednesday, February 8, 2012 7:18 AM
  • thats one cool thing about it. You can change the dataSource at anytime, the HTML source is then triggered to run the itemrenderer, in the case above-ListTemplate. which you can setup the way you want your list to be shown and what data to use from the JSON array.

    So yes, I have altered the dataSource and it re-populates via the renderer. So if something has been added, removed, whatever-it shows up.

    you only call the thisListView.dataSource=dataarray when you want to change/update it's contents.

    As mentioned above, I create a base JSON array that holds all the data that I want to display, and I mean everything! I then create new arrays based on that data.

    So with my example snippet from one of my apps, the first ListView is the main selector, you scroll through and find an Author, tap it, which triggers an iteminvoked event, which I then create and populate the second ListView based on the Authors, and since I don't think that the HTML itemrenderer can filter out data arrays, I have a routine that recreates my other JSON data array that is only specific to that Author.

    • Marked as answer by Bob_Bao Wednesday, March 7, 2012 6:58 AM
    Wednesday, February 8, 2012 4:10 PM

All replies

  • this may not work for you, but my lists work perfectly with a Promise.

    I use a .then statement so when the background task has finished, only then will the dataSource change/update.

    Tuesday, February 7, 2012 7:48 PM
  • The question is how do you update your datasource?

    What kind is ur datasource and which methods do U use to modify it? How does the view get notified about changes in the datasource it is bound to?

    Tuesday, February 7, 2012 8:48 PM
  • Does this sample work for you?  It updates my list view:

    http://social.msdn.microsoft.com/Forums/en-MY/winappswithhtml5/thread/af315065-c7af-49a4-9483-65dd2770b35f

    -Jeff


    Jeff Sanders (MSFT)

    Tuesday, February 7, 2012 9:09 PM
    Moderator
  •    

    HTML Setup:

    <divid="ListTemplate"data-win-control="WinJS.Binding.Template"style="display: none">


       

    <divclass="win-listview-mediumListIconTextTemplate">


       

    <imgclass="win-listview-mediumListIconTextTemplateImage"src="images/book.png"/>


       

    <divclass="win-listview-mediumListIconTextTemplateLargeText win-itemText"data-win-bind="innerText: title WinJS.Binding.oneTime"></div>


       

    </div>


       

    </div>  


       

    <divid="BooksListView"data-win-control="WinJS.UI.ListView"data-win-options="{dataSource: MyBooksDB, itemRenderer: ListTemplate, selectionMode: 'none', crossSlide: 'none', layout: {type: WinJS.UI.ListLayout} }">

    JavaScript Updater:

            thisListView

    =WinJS.UI.getControl(document.getElementById("BooksListView"));


            thisListView

    .dataSource =MyBooksDB;

    Building My database is done by a JSON array which I have by default in my app. But add to by pulling .xml from a server. But the most important thing to remember is that most of Win.JS is asynchronise. So our apps are not hanging on a callback. Just make sure you have a data array populated then point your dataSource to it.

    Hope this helps...

    • Edited by webdatadesigngroup Wednesday, February 8, 2012 7:34 AM
    • Marked as answer by Bob_Bao Wednesday, March 7, 2012 6:58 AM
    Wednesday, February 8, 2012 7:18 AM
  • Hmmm this assignes the dataSource each time new Data is fetched. Isn't that a bit unperformant? What happens if only one item has changed between the updates from the remote source? Does the listview recognize this and only removes this item from its displayed items?

    I am dealing with lots of items here and resetting the dataSource was not an option I thought.

    Wednesday, February 8, 2012 10:13 AM
  • thats one cool thing about it. You can change the dataSource at anytime, the HTML source is then triggered to run the itemrenderer, in the case above-ListTemplate. which you can setup the way you want your list to be shown and what data to use from the JSON array.

    So yes, I have altered the dataSource and it re-populates via the renderer. So if something has been added, removed, whatever-it shows up.

    you only call the thisListView.dataSource=dataarray when you want to change/update it's contents.

    As mentioned above, I create a base JSON array that holds all the data that I want to display, and I mean everything! I then create new arrays based on that data.

    So with my example snippet from one of my apps, the first ListView is the main selector, you scroll through and find an Author, tap it, which triggers an iteminvoked event, which I then create and populate the second ListView based on the Authors, and since I don't think that the HTML itemrenderer can filter out data arrays, I have a routine that recreates my other JSON data array that is only specific to that Author.

    • Marked as answer by Bob_Bao Wednesday, March 7, 2012 6:58 AM
    Wednesday, February 8, 2012 4:10 PM