Domanda

I'm creating a grouped list of my pupils as per this example: http://msdn.microsoft.com/en-us/library/windows/apps/hh465464.aspx The actual code for creating the grouping as well as the HTML are almost identical (safe for name changes).

I'm then push()ing some items into the original List() which then also updates the GroupedList(). That part works fine.

However, what I'm seeing is this:

List grouped by firstnames

This list should be grouped by firstnames (on display is "Lastname, Firstname"). What I'm seeing here is that item #1 should be in "S", #3 should be in "A" and #6 should be in "I".

The only thing that I'm doing different from the example is the DataSource, insofar as I'm push()ing an actual WinJS Class in there (with getter and setter functions for the attributes displayed in the List). However, the getGroupKey(dataItem) and other grouping functions are working as they should, i.e. return the proper values.

Any ideas? Because otherwise I'd have to look at using two arrays (one being the List() and another the array where the class instances live) for which I'd then have to program sync routines to keep the data consistent and that's something I actually wanted to escape from...

Code follows below, relevant snippets only.

Defining the Lists and grouping functions:

function compareGroups(leftKey, rightKey) { return leftKey.charCodeAt(0) - rightKey.charCodeAt(0); } function getGroupKey(dataItem) { return dataItem.lastname.toUpperCase().charAt(0); } function getGroupData(dataItem) { return { title: dataItem.lastname.toUpperCase().charAt(0) }; } var pupilsList = new WinJS.Binding.List({ binding: true }); var groupedPupilsList = pupilsList.createGrouped(getGroupKey, getGroupData, compareGroups);

Where the Data comes from:

var Schueler = WinJS.Class.define(function (original, id, firstname, lastname, tutor_id, picture, email, phone, notes, birthday, classes) {
    var that = this;
    this._classnames = new Array();
    if (original) {
        [... irrelevant part snipped ...]
        });
    } else {
        var row = id;
        this._id = row.rowid;
        this._firstname = row.firstname_enc;
        this._lastname = row.lastname_enc;
        this._tutor_id = row.tutor_id;
        this._picture = row.picture_enc;
        this._email = row.email_enc;
        this._phone = row.phone_enc;
        this._notes = row.notes_enc;
        this._birthday = row.birthday_enc;
        this._guid = row.guid;
        this.updateClassnames();
    }
},
{
    id: {
        get: function () {
            return this._id;
        },
        set: function (id) {
            this._id = id;
        }
    },
    firstname: {
        get: function () {
            return this._firstname;
        },
        set: function () {
            //TODO
        }
    },
    lastname: {
        get: function () {
            return this._lastname;
        },
        set: function () {
            //TODO
        }
    },
    [... irrelevant parts snipped ...]
    classnames: {
        get: function () {
            return this._classnames.join(", ");
        },
        set: function (names) {
            this._classnames = names;
        }
    },
    updateClassnames: function () {
        var that = this;
        SQLite3JS.openAsync(DataLayer.db_path)
        .then(function (db) {
            var sql = "SELECT Classes.name_enc FROM Classes JOIN Classes_Pupils ON Classes.rowid = Classes_Pupils.class_id JOIN Pupils ON Classes_Pupils.pupil_id = Pupils.rowid WHERE Pupils.rowid = {0};".format(that._id);
            return db.allAsync(sql)
            .then(function (results) {
                db.close();
                var names = new Array();
                for (var i = 0; i < results.length; i++) {
                    names.push(results[i].name_enc.toString().decrypt());
                }
                that.classnames = names;
                DataLayer.PupilsList.dispatchEvent("reload");
            }, function (error) {
                if (error.message.indexOf("database is locked") > -1) {
                    console.log("DB locked, will try again in 50 ms");
                    window.setTimeout(that.updateClassnames(), 50);
                }
            });
        });
    }
},
{
    reconstructAll: function () {
        DataLayer.retrieveSeveralRows("Pupils", function (results) {
            for (var i = 0; i < results.length; i++) {
                DataLayer.PupilsList.push(new Schueler(false, results[i]));
            }
        });
    }
});
WinJS.Namespace.define("DataLayer", {
    Schueler: Schueler
});

Workflow is as follows: First empty lists are created, then another routine checks for DB availability. As soon as that routine gives a green light, Schueler.reconstructAll() is called.

DataLayer.retrieveSeveralRows(table, callback) is a wrapper function for a call to the SQLite database, essentially doing a SELECT * FROM Pupils and returning the results to the callback function.

This callback then creates a new instance of the Schueler() class and pushes that to the list.

Addendum: If I use createSorted() everything is just dandy. Will use that for now.

Edit: As suggested by Kraig Brockschmidt, it seems to have indeed been a localization issues, so adding one line and modifying one function as follows fixes everything right up:

var charGroups = Windows.Globalization.Collation.CharacterGroupings();
function getGroupKey(dataItem) {
    return charGroups.lookup(dataItem.lastname.toUpperCase().charAt(0));
}
È stato utile?

Soluzione

I see that you're working with createSorted now, but there are a couple of other things you can do to diagnose the original issue.

First, try using some static data instead of populating your list dynamically.

Second, put some console.log output inside your getGroupKey and getGroupData functions so you can evaluate what you're returning, exactly.

The other thing I should mention is that the MSDN docs page shows code that isn't sensitive to all local languages. That is, using the first character of a string for sort order isn't always the right thing. There is an API in Windows.Globalization.Collation (http://msdn.microsoft.com/en-us/library/windows/apps/windows.globalization.collation.aspx) that is built to handle sort ordering properly. If you look at the [HTML ListView Grouping and Semantic Zoom sample][1], in the file groupeddata.js, you'll see how this is used. Offhand this shouldn't affect your data, but I wanted to mention it.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top