为什么我的WinJS Grouped Binding List会播放带有些物品的音乐椅?

时间:2014-03-29 19:37:24

标签: javascript data-binding winjs

我按照此示例创建了我的学生的分组列表:http://msdn.microsoft.com/en-us/library/windows/apps/hh465464.aspx 用于创建分组和HTML的实际代码几乎相同(对于名称更改是安全的)。

然后我将一些项目推送()到原始List()中,然后还更新GroupedList()。那部分工作正常。

然而,我所看到的是:

List grouped by firstnames

此列表应按名字分组(显示为"姓氏,名字和#34;)。我在这里看到的是第1项应该在" S",#3应该在" A"和#6应该在"我"。

我唯一与示例不同的是DataSource,因为我在那里push()实际的WinJS类(显示属性的getter和setter函数)在列表中)。 但是,getGroupKey(dataItem)和其他分组功能正在按预期工作,即返回正确的值。

有什么想法吗?因为否则我必须考虑使用两个数组(一个是List(),另一个是类实例所在的数组),然后我必须编写同步例程来保持数据的一致性。这是我真正想逃避的事情......

代码如下,相关的代码段。

定义列表和分组功能:

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);

数据来自:

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
});

工作流程如下:创建第一个空列表,然后另一个例程检查数据库可用性。只要该例程发出绿灯,就会调用Schueler.reconstructAll()

DataLayer.retrieveSeveralRows(table, callback)是一个调用SQLite数据库的包装函数,基本上是SELECT * FROM Pupils并将结果返回给回调函数。

然后,此回调会创建Schueler()类的新实例,并将其推送到列表中。

附录:如果我使用createSorted(),一切都只是花花公子。将暂时使用它。

编辑:正如Kraig Brockschmidt所建议的那样,它似乎确实存在本地化问题,因此添加一行并修改一个函数如下修复所有内容:

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

1 个答案:

答案 0 :(得分:1)

我发现您现在正在使用createSorted,但您可以采取其他一些措施来诊断原始问题。

首先,尝试使用一些静态数据,而不是动态填充列表。

其次,在你的getGroupKey和getGroupData函数中放入一些console.log输出,这样你就可以准确地评估你返回的内容。

我要提到的另一件事是,MSDN文档页面显示的代码对所有本地语言都不敏感。也就是说,使用字符串的第一个字符进行排序顺序并不总是正确的。 Windows.Globalization.Collat​​ion(http://msdn.microsoft.com/en-us/library/windows/apps/windows.globalization.collation.aspx)中有一个API,用于正确处理排序顺序。如果您查看文件groupeddata.js中的[HTML ListView Grouping and Semantic Zoom sample][1],您将会看到如何使用它。这不应该影响你的数据,但我想提一下。