PDA

View Full Version : HasMany association and "dirty" items...



mauzi75
3 Apr 2012, 1:48 AM
First a complete example:


//application
Ext.application({
models: [
'Team',
'Player'
],
stores: [
'Team'
],
views: [
'Team'
],
name: 'APP',
controllers: [
'Team'
],
launch: function() {
Ext.create('APP.view.Team', {fullscreen: true});
}


});




//controller
Ext.define('APP.controller.Team', {
extend: 'Ext.app.Controller',


config: {
control: {
"#Team": {
initialize: 'onTeamInitialize'
}
}
},


onTeamInitialize: function(component, options) {

var teamS = Ext.getStore("Team");
teamS.load(function(records, operation, success) {


teamS.getAt(0).players().load(function(records, operation, success) {
console.log(teamS);
},this);

}, this);
}


});




//view
Ext.define('APP.view.Team', {
extend: 'Ext.Panel',


config: {
id:"Team",
html:"<h1>Team</h1>"
}


});




//models
Ext.define('APP.model.Team', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'name',
type: 'string'
}
],
hasMany: {
model: 'APP.model.Player',
name: 'players'
},
proxy: {
type: 'ajax',
url: 'resources/debug/teams.js',
}
}
});


Ext.define('APP.model.Player', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'team_id',
type: 'int'
},
{
name: 'name',
type: 'string'
}
],
belongsTo: {
model: 'APP.model.Team',
name: 'team'
},
proxy: {
type: 'ajax',
url: 'resources/debug/players.js',
}
}
});




//store
Ext.define('APP.store.Team', {
extend: 'Ext.data.Store',
requires: [
'APP.model.Team'
],


config: {
model: 'APP.model.Team',
storeId: 'Team',
filters: {
property: 'id',
value: 1
}
}
});




//team.js (json file)
[
{
"id":1,
"name":"team 1"
},
{
"id":2,
"name":"team 2"
}
]


//player.js (json file)
[
{
"id":1,
"team_id":1,
"name":"player 1"
},
{
"id":2,
"team_id":1,
"name":"player 2"
},
{
"id":3,
"team_id":2,
"name":"player 3"
}
]


and here console output:


Team.js:33
Ext.apply.create.Class
_data: Ext.apply.create.Class
_filters: Ext.Object.classify.objectClass
_model: function () {
_modelDefaults: Ext.Object.classify.objectClass
_proxy: Ext.apply.create.Class
_remoteFilter: false
_remoteSort: false
_storeId: "Team"
_totalCount: null
config: Ext.Object.classify.objectClass
data: Ext.apply.create.Class
_autoFilter: true
_autoSort: true
_filterRoot: "data"
_filters: Ext.apply.create.Class
_sortRoot: "data"
all: Array[2]
config: Ext.Object.classify.objectClass
dirtyFilterFn: false
dirtyIndices: true
filterFn: function (item) {
filtered: true
getKey: function (record) {
indices: Object
initConfig: function (){}
initialConfig: Object
items: Array[1]
0: Ext.apply.create.Class
_data: Object
data: Object
id: 1
name: "team 1"
__proto__: Object
id: "ext-record-1"
internalId: 1
modified: Object
playersStore: Ext.apply.create.Class
_data: Ext.apply.create.Class
_filters: Array[1]
_model: function () {
_modelDefaults: Ext.Object.classify.objectClass
_proxy: Ext.apply.create.Class
_remoteFilter: true
_remoteSort: false
_storeId: "ext-data-store-1"
_totalCount: null
config: Ext.Object.classify.objectClass
data: Ext.apply.create.Class
_autoFilter: false
_autoSort: true
_filterRoot: "data"
_filters: Ext.apply.create.Class
_autoFilter: true
_autoSort: true
all: Array[1]
0: Ext.apply.create.Class
_exactMatch: true
_filterFn: function (item) {
_id: "team_id-1"
_property: "team_id"
_root: "data"
_value: 1
config: Ext.Object.classify.objectClass
initConfig: function (){}
initialConfig: Object
__proto__: TemplateClass
length: 1
__proto__: Array[0]
config: Ext.Object.classify.objectClass
getKey: function (filter) {
indices: Object
initConfig: function (){}
initialConfig: Object
items: Array[1]
keys: Array[1]
length: 1
map: Object
__proto__: TemplateClass
_sortRoot: "data"
all: Array[3]
0: Ext.apply.create.Class
1: Ext.apply.create.Class
2: Ext.apply.create.Class
_data: Object
data: Object
id: 3
name: "player 3"
team_id: 1
__proto__: Object
dirty: true
editing: false
id: "ext-record-5"
internalId: 3
modified: Object
team_id: 2
__proto__: Object
raw: Object
stores: Array[1]
__proto__: TemplateClass
length: 3
__proto__: Array[0]
config: Ext.Object.classify.objectClass
dirtyFilterFn: true
dirtyIndices: true
filtered: true
getKey: function (record) {
indices: Object
initConfig: function (){}
initialConfig: Object
items: Array[3]
keys: Array[3]
length: 3
map: Object
__proto__: TemplateClass
eventDispatcher: Ext.apply.create.Class
eventFiringSuspended: false
getEventDispatcher: function () {
getId: function () {
getObservableId: function () {
getUniqueId: function () {
id: "ext-data-store-1"
initConfig: function (){}
initialConfig: Object
loaded: true
loading: false
managedListeners: Object
observableId: "#ext-data-store-1"
removed: Array[0]
usedSelectors: Array[1]
__proto__: TemplateClass
raw: Object
stores: Array[1]
__proto__: TemplateClass
length: 1
__proto__: Array[0]
keys: Array[1]
length: 1
map: Object
__proto__: TemplateClass
eventDispatcher: Ext.apply.create.Class
eventFiringSuspended: false
getEventDispatcher: function () {
getId: function () {
getObservableId: function () {
getUniqueId: function () {
id: "app-store-team-1"
initConfig: function (){}
initialConfig: Object
loaded: true
loading: false
managedListeners: Object
observableId: "#app-store-team-1"
removed: Array[0]
usedSelectors: Array[1]
__proto__: TemplateClass




The scope of this code is to load manually data into the Team store (this is done in team view initialize event in the example). The issue is that the function "load" of players store inside team does not filter players by team id.


This happens because "load" function modifies player data: looking at console output, the code in red shows that "player 3" record is marked as "dirty" and its team_id value is modified to match the id of team.


So, what is wrong in the configuration? How to avoid "dirty" items?

mitchellsimoens
3 Apr 2012, 7:09 AM
So you are wanting a config that will prevent the dirty status?

mauzi75
3 Apr 2012, 1:29 PM
When I load players of a team, I'm expecting to find only the players of that team in the store, but the example loads all players inside players.js json file without filter them by team id.


The function team.players().load() fill players store with records read from the file, but it changes third record and modifies team_id value to match the team id, so the store does not filter players.

romulus2012
20 Apr 2012, 11:17 PM
Hi,
Did you find a solution? I'm having the same problem ...

mauzi75
21 Apr 2012, 12:52 AM
no, i did not find a solution. I've changed all the strategy to load data. Instead of having two json files for the different sources data, now I use only a file with nested items, as in this example:




//teams.js (json file)
[
{
"id":1,
"name":"team 1",
"players":[
{
"id":1,
"team_id":1,
"name":"player 1"
},
{
"id":2,
"team_id":1,
"name":"player 2"
}
]
},
{
"id":2,
"name":"team 2",
"players":[
{
"id":3,
"team_id":2,
"name":"player 3"
}
]
}
]



consequently store and models code changes:




//models
Ext.define('APP.model.Team', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'name',
type: 'string'
}
],
hasMany: {
model: 'APP.model.Player',
name: 'players'
}
}
});




Ext.define('APP.model.Player', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'team_id',
type: 'int'
},
{
name: 'name',
type: 'string'
}
],
belongsTo: {
model: 'APP.model.Team',
name: 'team'
}
}
});








//store
Ext.define('APP.store.Team', {
extend: 'Ext.data.Store',
requires: [
'APP.model.Team'
],




config: {
model: 'APP.model.Team',
storeId: 'Team',
filters: {
property: 'id',
value: 1
}
proxy: {
type: 'ajax',
url: 'resources/debug/teams.js',
}
}
});



in this way works.

romulus2012
21 Apr 2012, 5:09 AM
Hi,
Thank you for your answer. I'm trying to use this but i don't know how to access data from a Controller.

mauzi75
22 Apr 2012, 12:51 AM
Take a look at the example in the first post: the controller inside it accesses to data of the store.


The example manually loads data, but if you use autoload, Ext.getStore function returns the store and all data are already inside it.