質問:
ストアからの階層データが取り込まれた Ext.List をフィルタリングするための推奨される方法は何ですか? フィルターで選択した親オブジェクトに属する子オブジェクトを除外する必要があります。子 (この場合はゲーム)がリストに入力されます。
必要なもの
- Ext.List は、「Omgång 1」、「Omgång 2」などのラウンドでフィルタリングできる必要があります。(「Omgång」 = スウェーデン語で「ラウンド」) フィルタとして「Omgång 1」を選択すると、リストにはそのラウンドのゲームのみが表示されます。以下の JSON ドキュメントを参照してください。
- リストは日付 (「kickOff」) でグループ化し、「gameId」ASC で並べ替える必要があります。
私がやった事
- ReST プロキシ経由で読み取った JSON ドキュメントからデータを取得する Ext.data.Store 経由で取得したデータが入力された Ext.List を作成しました。
- Ext.List は、ストア Rounds からデータを読み取ります (以下を参照)。問題は、ラウンド「Omgång 1」で 8 つのゲームがあるはずなのに、1 つのゲームしか表示されないことです。
これは私がこれまでに達成したことです。リストはボタンを使用してフィルタリングされますが、リスト項目の 1 つだけが表示されます。
EM.model.Round
ラウンド用モデル。Match とは 1 対多の関係にあります。
Ext.define('EM.model.Round', {
extend: 'Ext.data.Model',
init: function() {},
config: {
storeId: 'Rounds',
fields: [
'name',
'lockedDate',
],
associations: {
type: 'hasMany',
model: 'EM.model.Match',
primaryKey: 'gameId',
name: 'matches',
autoLoad: true,
associationKey: 'games'
}
},
});
EM.model.Match
マッチのモデル。ラウンド所属です。
Ext.define('EM.model.Match', {
extend: 'Ext.data.Model',
init: function() {},
config: {
fields: [
{
name: 'gameId',
type: 'int'
},
{
name: 'firstTeam',
type: 'string'
},
{
name: 'firstTeamClass',
type: 'string',
convert: function(value, record) {
return util.convertFieldValueToLowerCase('firstTeam', record);
}
},
{
name: 'secondTeam',
type: 'string'
},
{
name: 'secondTeamClass',
type: 'string',
convert: function(value, record) {
return util.convertFieldValueToLowerCase('secondTeam', record);
}
},
'kickOff',
{
name: 'kickOffHour',
convert: function(value, record) {
var timestamp = new Date(util.convertUnixTimeToMilliseconds(record.get('kickOff')));
return Ext.Date.format(timestamp, 'H:i');
}
},
{
name: 'firstTeamGoals',
type: 'int',
defaultValue: 0
},
{
name: 'secondTeamGoals',
type: 'int',
defaultValue: 0
},
{
name: 'firstTeamGoalsBet',
},
{
name: 'secondTeamGoalsBet',
},
'points',
{
name: 'pointsEarned',
convert: function(value, record) {
var className = 'no-points-earned';
var points = record.get('points');
if (typeof points == 'undefined') {
return '';
}
if (points > 0) {
className = 'points-earned';
}
return '<div class="' + className + '">' + points + '</div>'
}
},
],
associations: {
type: 'belongsTo',
model: 'EM.model.Round',
name: 'round',
autoLoad: true
}
}
});
EM.store.Rounds
JSON ドキュメントを読み取るストア。このストアは、Ext.List に入力するために使用されます。
Ext.define('EM.store.Rounds', {
extend: 'Ext.data.Store',
config: {
model: 'EM.model.Round',
storeId: 'Rounds',
filters: [{
property: 'name',
value: 'Round 1'
}],
/*grouper: {
groupFn: function (item) {
//var kickOff = new Date(util.convertUnixTimeToMilliseconds(item.get('kickOff')));
//return kickOff.format('d mmmm yyyy');
},
//sortProperty: 'kickOff'
},*/
proxy: {
type: 'rest',
url : 'resources/json/matches.json',
reader: {
type: 'json',
}
},
autoLoad: true,
}
});
JSON ドキュメント
これは、 EM.store.Roundsでプロキシによって読み取られる JSON ドキュメントです。
[
{
"name": "Omgång 1",
"lockedDate": 1325420111,
"games": [
{
"gameId": 1,
"firstTeam": "Pol",
"secondTeam": "Gre",
"kickOff": 1339178400,
"firstTeamGoals": 0,
"secondTeamGoals": 3,
"firstTeamGoalsBet": 0,
"secondTeamGoalsBet": 3,
"points": 3
},
{
"gameId": 2,
"firstTeam": "Rus",
"secondTeam": "Cze",
"kickOff": 1339188300,
"firstTeamGoals": 4,
"secondTeamGoals": 1,
"firstTeamGoalsBet": 1,
"secondTeamGoalsBet": 2,
"points": 0
},{
"gameId": 3,
"firstTeam": "Ned",
"secondTeam": "Den",
"kickOff": 1339264800,
"firstTeamGoals": 2,
"secondTeamGoals": 1,
"firstTeamGoalsBet": 4,
"secondTeamGoalsBet": 2,
"points": 2
},
{
"gameId": 4,
"firstTeam": "Ger",
"secondTeam": "Por",
"firstTeamGoalsBet": 4,
"secondTeamGoalsBet": 0,
"kickOff": 1339274700
},
{
"gameId": 5,
"firstTeam": "Spa",
"secondTeam": "Ita",
"firstTeamGoalsBet": 3,
"secondTeamGoalsBet": 2,
"kickOff": 1339351200
},
{
"gameId": 6,
"firstTeam": "Irl",
"secondTeam": "Cro",
"kickOff": 1339361100
},
{
"gameId": 7,
"firstTeam": "Fra",
"secondTeam": "Eng",
"kickOff": 1339437600
},
{
"gameId": 8,
"firstTeam": "Ukr",
"secondTeam": "Swe",
"kickOff": 1339447500
}
]
},
{
"name": "Omgång 2",
"games": [
{
"gameId": 4,
"firstTeam": "Gre",
"secondTeam": "Cze",
"kickOff": 1339524000
}
]
},
{
"name": "Omgång 3",
"games": [
{
"gameId": 4,
"firstTeam": "Gre",
"secondTeam": "Rus",
"kickOff": 1339869600
}
]
},
{
"name": "Kvart",
"games": [
{
"gameId": 4,
"firstTeam": "1A",
"secondTeam": "2B",
"kickOff": 1340311500
}
]
},
{
"name": "Semi",
"games": [
{
"gameId": 4,
"firstTeam": "#25",
"secondTeam": "#27",
"kickOff": 1340829900
}
]
},
{
"name": "Final",
"games": [
{
"gameId": 4,
"firstTeam": "#29",
"secondTeam": "#30",
"kickOff": 1341175500
}
]
}
]
EM.view.MatchList
一致したリストを表示するリスト ビュー。
Ext.define('EM.view.MatchList', {
extend: 'Ext.List',
xtype: 'matchlist',
requires: [
'Ext.TitleBar',
'EM.store.Rounds'
],
config: {
id: 'match-list',
store: 'Rounds',
//grouped: true,
scrollable: false,
items: [
{
xtype: 'titlebar',
scrollable: {
direction: 'horizontal',
directionLock: true
},
items: [
{
xtype: 'button',
text: 'Omgång 1',
handler: function() {
var sto = Ext.getStore('Rounds');
sto.clearFilter();
sto.filter('name', 'Omgång 1');
console.log(sto);
}
},
{
xtype: 'button',
text: 'Omgång 2',
handler: function() {
var sto = Ext.getStore('Rounds');
sto.clearFilter();
sto.filter('name', 'Omgång 2');
}
},
{
xtype: 'button',
text: 'Omgång 3',
handler: function() {
var sto = Ext.getStore('Rounds');
sto.clearFilter();
sto.filter('name', 'Omgång 3');
}
},
{
xtype: 'button',
text: 'Kvart',
handler: function() {
var sto = Ext.getStore('Rounds');
sto.clearFilter();
sto.filter('name', 'Kvart');
}
},
{
xtype: 'button',
text: 'Semi',
handler: function() {
var sto = Ext.getStore('Rounds');
sto.clearFilter();
sto.filter('name', 'Semi');
}
},
{
xtype: 'button',
text: 'Final',
handler: function() {
var sto = Ext.getStore('Rounds');
sto.clearFilter();
sto.filter('name', 'Final');
}
}
],
},
{
xtype: 'panel',
html: 'Senast uppdaterad: Idag kl 20:12'
}
],
itemTpl: [
'<div class="match-meta-data">',
'<tpl for="matches">',
'<div class="team-wrapper home-team">{firstTeam} <div class="flag {firstTeamClass}"><span></span></div> <span class="goals-scored">{firstTeamGoals}</span></div>',
'<div class="kick-off-time">{kickOffHour}</div>',
'<div class="team-wrapper away-team"><span class="goals-scored">{secondTeamGoals}</span> <div class="flag {secondTeamClass}"><span></span></div> {secondTeam}</div>',
'<div class="bet-meta-data">',
'<img class="user-icon" src="resources/images/user-22x26.png" />',
'<div class="home-team goals-bet">{firstTeamGoalsBet}</div>',
'<div class="away-team goals-bet">{secondTeamGoalsBet}</div>',
'{pointsEarned}',
'</div>',
'</tpl>',
'</div>',
].join('')
},
});
これは私の初めての Sencha Touch アプリなので、コードに見られる悪い慣行があれば遠慮なく指摘してください。誰かが私が目指していることを達成する方法の例を教えてください。私はこれを理解しようと多くの時間を費やしました。
完全なプロジェクトは、 https://github.com/eriktoyra/EM-Tipsetの GitHub からダウンロードできます。最新のブランチは _filter-match-list です。