locked
WinJS.Binding.List setAt method

    Question

  • I am trying to update the tile in a listview when clicked.  The iteminvoked function is:

            itemInvoked: function (eventObject) {
                var item = list.getAt(eventObject.detail.itemIndex);
                var count = item.countnum + 1;
                var updatedItem = {
                    group: item.group,
                    title: item.title,
                    countnum: count,
                    backgroundColor: "rgba(190,180,220,0.6)"
                };
                list.setAt(eventObject.detail.itemIndex, updatedItem);
            }

    When I click on an item, the following exception is throw:

     Exception was thrown at line 4973, column 9 in ms-appx://microsoft.winjs.0.6.debug-8wekyb3d8bbwe/js/base.js
     0x800a138f - JavaScript runtime error: Unable to get value of the property 'insertBefore': object is null or undefined

    When I continue from this error, I can see that the list.setAt worked, but then the following exception is thrown:

     Unhandled exception at line 5012, column 13 in ms-appx://microsoft.winjs.0.6.debug-8wekyb3d8bbwe/js/base.js
     0x800a138f - JavaScript runtime error: Unable to get value of the property 'release': object is null or undefined

    Am I using the list.setAt method incorrectly, or is there a problem in WinJS?

    Sunday, March 18, 2012 4:53 PM

Answers

  • Hi,

    Thanks for the demo. According to the document we need to use msSetImmediate to change datasource or else DOM of the changed element is not created when ListView is setting its focus and thus causes this error. however based on my test it still doesn't work if you click very quickly. It might be related with some known issues of msSetImmediate in CP. No good solution at this moment, unfortunately.

    http://msdn.microsoft.com/en-us/library/windows/apps/br211827.aspx

     itemInvoked: function (eventObject) {
    
                msSetImmediate(function (arg) {
                    var item = data.items.getAt(arg.detail.itemIndex);
                    var count = item.count + 1;
                    var updatedItem = {
                        group: item.group,
                        title: item.title,
                        count: count,
                        description: item.description,
                        content: item.content,
                        backgroundImage: item.backgroundImage
                    };
    
                    data.items.setAt(arg.detail.itemIndex, updatedItem);
            }, eventObject);
           
    
            }


    Allen Chen [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Wednesday, March 21, 2012 7:09 AM

All replies

  • Hi,

    Could you create a demo that can reproduce the problem and post all code here?


    Allen Chen [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, March 19, 2012 9:22 AM
  • This problem is happening in one small part of a large app, so I took a different approach.  I created the demo from a new Grid Application project. Then changed the groupedItemsPage.html, data.js, and groupedItemsPage.js as shown below.  This produces the same results as I in my app.

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>groupedItemsPage</title>
        
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet">
        <script src="//Microsoft.WinJS.0.6/js/base.js"></script>
        <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>
        
        <link href="/css/default.css" rel="stylesheet">
        <link href="/css/groupedItemsPage.css" rel="stylesheet">
        <script src="/js/data.js"></script>
        <script src="/js/groupedItemsPage.js"></script>
    </head>
    <body>
        <!-- These templates are used to display each item in the ListView declared below. -->
        <div class="headerTemplate" data-win-control="WinJS.Binding.Template">
            <h2 class="group-title" data-win-bind="onclick: click; textContent: title" role="link"></h2>
        </div>
        <div class="itemtemplate" data-win-control="WinJS.Binding.Template">
            <img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" />
            <div class="item-overlay">
                <h4 class="item-title" data-win-bind="textContent: title"></h4>
                <h6 class="item-subtitle win-type-ellipsis" data-win-bind="innerText: count"></h6>
            </div>
        </div>
    
        <!-- The content that will be loaded and displayed. -->
        <div class="fragment groupeditemspage">
            <header aria-label="Header content" role="banner">
                <button class="win-backbutton" aria-label="Back" disabled></button>
                <h1 class="titlearea win-type-ellipsis">
                    <span class="pagetitle">Demo2</span>
                </h1>
            </header>
            <section aria-label="Main content" role="main">
                <div class="groupeditemslist" aria-label="List of groups" data-win-control="WinJS.UI.ListView" data-win-options="{ selectionMode: 'none', editable: true }"></div>
            </section>
        </div>
    </body>
    </html>


    (function () {
        "use strict";
        var groupDescription = "Group Description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus tempor scelerisque lorem in vehicula. Aliquam tincidunt, lacus ut sagittis tristique, turpis massa volutpat augue, eu rutrum ligula ante a ante";
        var itemDescription = "Item Description: Pellentesque porta mauris quis interdum vehicula urna sapien ultrices velit nec venenatis dui odio in augue cras posuere enim a cursus convallis neque turpis malesuada erat ut adipiscing neque tortor ac erat";
        var itemContent = "<p>Curabitur class aliquam vestibulum nam curae maecenas sed integer cras phasellus suspendisse quisque donec dis praesent accumsan bibendum ";
        var lightGray = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY7h4+cp/AAhpA3h+ANDKAAAAAElFTkSuQmCC";
        var mediumGray = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY5g8dcZ/AAY/AsAlWFQ+AAAAAElFTkSuQmCC";
        var darkGray = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY3B0cPoPAANMAcOba1BlAAAAAElFTkSuQmCC";
        var sampleGroups = [
            { key: "group1", title: "Group Title: 1", subtitle: "Group Subtitle: 1", backgroundImage: darkGray, description: groupDescription },
            { key: "group2", title: "Group Title: 2", subtitle: "Group Subtitle: 2", backgroundImage: lightGray, description: groupDescription },
            { key: "group3", title: "Group Title: 3", subtitle: "Group Subtitle: 3", backgroundImage: mediumGray, description: groupDescription }
        ];
        var sampleItems = [
            { group: sampleGroups[0], title: "Item Title: 1", count: 0, description: itemDescription, content: itemContent, backgroundImage: lightGray },
            { group: sampleGroups[0], title: "Item Title: 2", count: 0, description: itemDescription, content: itemContent, backgroundImage: darkGray },
            { group: sampleGroups[0], title: "Item Title: 3", count: 0, description: itemDescription, content: itemContent, backgroundImage: mediumGray },
            { group: sampleGroups[0], title: "Item Title: 4", count: 0, description: itemDescription, content: itemContent, backgroundImage: darkGray },
            { group: sampleGroups[0], title: "Item Title: 5", count: 0, description: itemDescription, content: itemContent, backgroundImage: mediumGray },
            
            { group: sampleGroups[1], title: "Item Title: 1", count: 0, description: itemDescription, content: itemContent, backgroundImage: darkGray },
            { group: sampleGroups[1], title: "Item Title: 2", count: 0, description: itemDescription, content: itemContent, backgroundImage: mediumGray },
            { group: sampleGroups[1], title: "Item Title: 3", count: 0, description: itemDescription, content: itemContent, backgroundImage: lightGray },
    
            { group: sampleGroups[2], title: "Item Title: 1", count: 0, description: itemDescription, content: itemContent, backgroundImage: mediumGray },
            { group: sampleGroups[2], title: "Item Title: 2", count: 0, description: itemDescription, content: itemContent, backgroundImage: lightGray },
            { group: sampleGroups[2], title: "Item Title: 3", count: 0, description: itemDescription, content: itemContent, backgroundImage: darkGray },
            { group: sampleGroups[2], title: "Item Title: 4", count: 0, description: itemDescription, content: itemContent, backgroundImage: lightGray },
            { group: sampleGroups[2], title: "Item Title: 5", count: 0, description: itemDescription, content: itemContent, backgroundImage: mediumGray },
            { group: sampleGroups[2], title: "Item Title: 6", count: 0, description: itemDescription, content: itemContent, backgroundImage: darkGray },
            { group: sampleGroups[2], title: "Item Title: 7", count: 0, description: itemDescription, content: itemContent, backgroundImage: mediumGray }
        ];
        function groupKeySelector(item) {
            return item.group.key;
        }
        function groupDataSelector(item) {
            return item.group;
        }
        function getItemsFromGroup(group) {
            return list.createFiltered(function (item) { return item.group.key === group.key; });
        }
        var list = new WinJS.Binding.List();
        var groupedItems = list.createGrouped(groupKeySelector, groupDataSelector);
        sampleItems.forEach(function (item) {
            list.push(item);
        });
        WinJS.Namespace.define("data", {
            items: groupedItems,
            groups: groupedItems.groups,
            getItemsFromGroup: getItemsFromGroup
        });
    })();
    (function () {
        "use strict";
        var appView = Windows.UI.ViewManagement.ApplicationView;
        var appViewState = Windows.UI.ViewManagement.ApplicationViewState;
        var nav = WinJS.Navigation;
        var ui = WinJS.UI;
        var utils = WinJS.Utilities;
        ui.Pages.define("/html/groupedItemsPage.html", {
            groupDataSelector: function (item) {
                return { title: item.group.title, click: function () { nav.navigate("/html/groupDetailPage.html", { group: item.group });
                    }
                }
            },
            groupKeySelector: function (item) { return item.group.key; },
            itemInvoked: function (eventObject) {
                var item = data.items.getAt(eventObject.detail.itemIndex);
                var count = item.count + 1;
                var updatedItem = {
                    group: item.group,
                    title: item.title,
                    count: count,
                    description: item.description, 
                    content: item.content, 
                    backgroundImage: item.backgroundImage
                };
                data.items.setAt(eventObject.detail.itemIndex, updatedItem);
            },
            ready: function (element, options) {
                var listView = element.querySelector(".groupeditemslist").winControl;
                ui.setOptions(listView, {
                    groupHeaderTemplate: element.querySelector(".headerTemplate"),
                    itemTemplate: element.querySelector(".itemtemplate"),
                    oniteminvoked: this.itemInvoked.bind(this)
                });
                this.updateLayout(element, appView.value);
            },
            updateLayout: function (element, viewState) {
                var listView = element.querySelector(".groupeditemslist").winControl;
                if (viewState === appViewState.snapped) {
                } else {
                    var groupDataSource = data.items.createGrouped(this.groupKeySelector, this.groupDataSelector).groups;
                    ui.setOptions(listView, {
                        itemDataSource: data.items.dataSource,
                        groupDataSource: groupDataSource.dataSource,
                        layout: new ui.GridLayout({ groupHeaderPosition: "top" })
                    });
                }
            },
    
        });
    })();

    The intent of the changes are to display a count on each tile and increment the count each time the tile is pressed. I hope this provides you with the detail you need.

    Tuesday, March 20, 2012 5:19 PM
  • Hi,

    Thanks for the demo. According to the document we need to use msSetImmediate to change datasource or else DOM of the changed element is not created when ListView is setting its focus and thus causes this error. however based on my test it still doesn't work if you click very quickly. It might be related with some known issues of msSetImmediate in CP. No good solution at this moment, unfortunately.

    http://msdn.microsoft.com/en-us/library/windows/apps/br211827.aspx

     itemInvoked: function (eventObject) {
    
                msSetImmediate(function (arg) {
                    var item = data.items.getAt(arg.detail.itemIndex);
                    var count = item.count + 1;
                    var updatedItem = {
                        group: item.group,
                        title: item.title,
                        count: count,
                        description: item.description,
                        content: item.content,
                        backgroundImage: item.backgroundImage
                    };
    
                    data.items.setAt(arg.detail.itemIndex, updatedItem);
            }, eventObject);
           
    
            }


    Allen Chen [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Wednesday, March 21, 2012 7:09 AM
  • This worked great.  Thanks for your help.
    Wednesday, March 21, 2012 9:29 PM