我按照此示例创建了我的学生的分组列表:http://msdn.microsoft.com/en-us/library/windows/apps/hh465464.aspx 用于创建分组和HTML的实际代码几乎相同(对于名称更改是安全的)。
然后我将一些项目推送()到原始List()中,然后还更新GroupedList()。那部分工作正常。然而,我所看到的是:
此列表应按名字分组(显示为"姓氏,名字和#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));
}
答案 0 :(得分:1)
我发现您现在正在使用createSorted,但您可以采取其他一些措施来诊断原始问题。
首先,尝试使用一些静态数据,而不是动态填充列表。
其次,在你的getGroupKey和getGroupData函数中放入一些console.log输出,这样你就可以准确地评估你返回的内容。
我要提到的另一件事是,MSDN文档页面显示的代码对所有本地语言都不敏感。也就是说,使用字符串的第一个字符进行排序顺序并不总是正确的。 Windows.Globalization.Collation(http://msdn.microsoft.com/en-us/library/windows/apps/windows.globalization.collation.aspx)中有一个API,用于正确处理排序顺序。如果您查看文件groupeddata.js中的[HTML ListView Grouping and Semantic Zoom sample][1]
,您将会看到如何使用它。这不应该影响你的数据,但我想提一下。