过滤使用商店中的分层数据填充的Ext.List的推荐方法是什么?我需要过滤掉属于我选择过滤的父对象的子对象。孩子们,在这种情况下游戏应该填充列表。
这是我迄今为止所取得的成就。使用按钮过滤列表,但只显示其中一个列表项。
Round的模型。它与Match有一对多的关系。
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'
}
},
});
匹配模型。它属于Round。
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
}
}
});
读取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,
}
});
这是 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
}
]
}
]
显示匹配列表的列表视图。
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。
答案 0 :(得分:0)
这些确实是两个问题。我不知道为什么你的整个商店似乎没有在列表视图中呈现;一些踩踏和暂停可能会对此有所了解。如果您在某个地方举办过演示,我很乐意看一下。
关于你的多轮过滤问题,我现在可以想到两件事:
据我所知,对商店执行filter
操作会导致它“丢失”数据,即丢弃与过滤器不匹配的所有数据(而不是将其隐藏在存储器中) )。如果您在同一服务器调用中将所有轮次加载到一个商店中,我不确定过滤是否适合您。我可能错了,但我只是尝试从Javascript控制台中过滤我的一个应用程序中的商店;当我应用了一个与任何项目都不匹配的过滤器时,商店就会清空。基于此,过滤可能不是最好的事情。
为每轮创建一个单独的listview
,每个轮次使用相同的公共轮次存储。使用itemTpl
配置和XTemplate
来确定哪些匹配应该放入每个列表中。根据需要,使用Omgång按钮从视口中交换这些列表。
在更好地了解您的问题和代码后更新答案
答案 1 :(得分:0)
我设法通过使用类似于我的实际测试场景来找到解决此问题的方法。
我做的是:
下面提供了完整的解决方案,也可以在GitHub上找到。
如果其他人应该找到更好的解决方案或指出一些改进,我会在几天内保持这个问题没有答案。
/**
* @description The main purpose of this mockup is to test how to filter a list using hierarchical data. The code is adapted from the example
* "Filtering data in an Ext.List component in Sencha Touch 2" by Peter deHaan.
* @see <a href="http://senchaexamples.com/2012/03/15/filtering-data-in-an-ext-list-component-in-sencha-touch-2/">Filtering data in an Ext.List component in Sencha Touch 2</a>.
* @author <a href="mailto:erik.toyra[at]gmail.com">Erik Töyrä</a>
*/
Ext.application({
launch: function () {
/**
* Division model
*/
Ext.define("Division", {
extend: 'Ext.data.Model',
config: {
fields: [
'division'
],
// Setup a hasMany relations between Division and Team
hasMany: {model: 'Team', name: 'teams'},
// Load data from teams.json into the Division model
proxy: {
type: 'rest',
url : 'teams.json',
reader: {
type: 'json'
}
}
}
});
/**
* Team model
*/
Ext.define("Team", {
extend: 'Ext.data.Model',
config: {
fields: [
'name', 'league'
],
// Setup a belongsTo relationship between Team and Division
belongsTo: {model: 'Division'},
}
});
/**
* Division store
*/
var divisionStore = Ext.create('Ext.data.Store', {
model: "Division",
storeId: 'divisionStore',
});
/**
* Team store
*/
var teamStore = Ext.create('Ext.data.Store', {
model: "Team",
storeId: 'teamStore', // This is the store we will reference in our Ext.list below.
fields: ['division', 'leage', 'name'],
});
/**
* Load the Division store which holds all of the data read from teams.json.
* After the data has been loaded we add the team data to the teamStore.
*/
divisionStore.load({
callback: function() {
// Loop through each division and retrieve the all teams that resides as
// childs to the division. Then we add each team to the teamStore.
divisionStore.each(function(division) {
division.teams().each(function(team) {
teamStore.add(team);
});
});
}
});
/**
* Create the list that should be filtered by Division and display a filtered list with Team objects.
*/
Ext.create('Ext.List', {
fullscreen: true,
items: [{
xtype: 'titlebar',
docked: 'top',
ui: 'neutral',
items: [{
text: 'West only',
handler: function () {
return util.doFilter('West');
} // handler
}, {
text: 'Central only',
handler: function () {
return util.doFilter('Central');
} // handler
}, {
text: 'East only',
handler: function () {
return util.doFilter('East');
} // handler
}, {
text: 'Clear filters',
ui: 'decline',
align: 'right',
handler: function () {
Ext.getStore('teamStore').clearFilter();
} // handler
}
] // items (toolbar)
}], // items (list)
store: 'teamStore',
itemTpl: '{name}, {league}',
}); // create()
/**
* Utility functions
*/
var util = (function() {
var util = {};
/**
* Filter the teamStore by the passed in Division name.
*/
util.doFilter = function(filterOption) {
var store = Ext.getStore('teamStore');
// Clear all existing filters first...
store.clearFilter();
// ... then apply the selected filter
store.filterBy(function(record, id) {
return record.getDivision().get('division') == filterOption;
}, this);
}
return util;
})();
} // launch
}); // application()
[
{
division: 'East',
teams: [
{
name: 'New York Yankees',
league: 'AL',
}, {
name: 'Tampa Bay',
league: 'AL',
}, {
name: 'Boston',
league: 'AL',
}, {
name: 'Toronto',
league: 'AL',
}, {
name: 'Baltimore',
league: 'AL',
}
]
},
{
division: 'Central',
teams: [
{
name: 'Detroit',
league: 'AL',
}, {
name: 'Cleveland',
league: 'AL',
}, {
name: 'Chicago White Sox',
league: 'AL',
}, {
name: 'Kansas City',
league: 'AL',
}, {
name: 'Minnesota',
league: 'AL',
}
]
},
{
division: 'West',
teams: [
{
name: 'Texas',
league: 'AL',
}, {
name: 'Los Angeles Angels',
league: 'AL',
}, {
name: 'Oakland',
league: 'AL',
}, {
name: 'Seattle',
league: 'AL',
}
]
}
]