0
votes

I have two models in my ExtJS (4.2.1) application and would like to define a "hasOne" asscociation between the two models. However, I can't make it work.

I tryed to respect the rules for the "hasOne" association as indicated in http://extjs-tutorials.blogspot.ch/2012/05/extjs-belongsto-association-rules.html.

Main Model

Ext.define('Aap.model.TreeNode', {
extend: 'Ext.data.Model',
fields: [
    { name: 'name', type: "string"},
    { name: 'id'},
    { name: 'allgemein_id'}
],
proxy: {
    type: 'ajax',
    url: 'data/treedata.json',
    reader: {
        type: 'json',
        root: 'nodes',
        successProperty: 'success'
    }
},
associations: [
    {
        type: 'hasOne',
        model: 'Aap.model.Allgemein',
        associationKey: 'metaallgemein',
        primaryKey: 'id',
        foreignKey: 'allgemein_id',
        getterName: 'getAllgemein',
        setterName: 'setAllgemein',
        autoLoad: true
    }
]

});

Associated model

Ext.define('Aap.model.Allgemein', {
extend: 'Ext.data.Model',
requires: 'Aap.model.TreeNode',
fields: [
    {name: "name", type: 'string'}, 
    {name: "allgemein_name", type: 'string'}, 
    {name: "ident", type: 'string'}, 
    {name: "georefdat", type: 'string'},
    {name: "fachst", type: 'string'}, 
    {name: "zugberech", type: 'string'}, 
    {name: "echkateg", type: 'string'}, 
    {name: "nachfzeitr", type: 'string'}, 
    {name: "datenmenge"}, 
    {name: "imjr"}, 
    {name: "datenzuw"}, 
    {name: "bemerk", type: 'string'},
    {name: "treenode_id", type: 'int'},
    {name: "id", type: "int"}
],
associations: [
    {
        type: 'belongsTo',
        model: 'Aap.model.TreeNode'
    }
],
proxy: {
    type: 'ajax',
    api: {
        read: 'data/allgemeindata.json'
    },  
    reader: {
        type: 'json',
        root: 'metaallgemein',
        successProperty: 'success'
    }
}

});

Data for main model

{
"success": true,
"nodes": [
    { "name": "st", "id":"1", "allgemein_id": "1", "expanded": false, "children": [
        { "name": "Geodätische Grundlagen", "id":"4", "allgemein_id": "4", "children": [
            { "name": "Beispiel Datensatz", "id":"6", "allgemein_id": "6", "leaf": true }
        ]},
        { "name": "Bilddaten", "id":"5", "allgemein_id": "5", "loaded": true}
    ]},
    { "name": "BU", "id":"2", "allgemein_id": "2", "loaded": true },
    { "name": "BE", "id":"3", "allgemein_id": "3", "loaded": true }
]

}

Data of associated model

{
"success": true,
"metaallgemein": [
    { 
        "name":"st", 
        "ident": "stident", 
        "georefdat":"stgeorefdat",
        "fachst":"stfach", 
        "zugberech":"stzugangsbe", 
        "echkateg":"stechkateg", 
        "nachfzeitr":"stzeitrnachf", 
        "datenmenge":"stdatenmende", 
        "imjr":"stimjr", 
        "datenzuw":"stdatenzuw", 
        "bemerk":"stbemerk",
        "id": "1",
        "treenode_id": "ext-record-1"
    },
    { 
        "name":"BU", 
        "ident": "buident", 
        "georefdat":"bugeorefdat",
        "fachst":"bufach", 
        "zugberech":"buzugangsbe", 
        "echkateg":"buechkateg", 
        "nachfzeitr":"buzeitrnachf", 
        "datenmenge":"budatenmende", 
        "imjr":"buimjr", 
        "datenzuw":"budatenzuw", 
        "bemerk":"bubemerk",
        "id": "2",
        "treenode_id": "ext-record-2"
    }, ...
            ...
            ...

When I load my page and try to get the associated data with my getter, the following happens (see image).

  • The first time I try to get the associated data (rec.getAllgemein()), I don not get any data.
  • When I use the getter a second time (rec.getAllgemein()), I get data, but not the correct ones. I added a Screenshot helping to explain the problem. It seem to be a more fundametal problem. Some data are associated, but not correctly. Other record do not have any association.

I tried a simpler example in order to trace the problem. But I did not even achieve to make the association work in the most basic example. It seems that I make somewhere a fundametal mistake:

Ext.define('Aap.model.Person', {
extend: 'Ext.data.Model',
requires: 'Aap.model.Address',
fields: [
    {name: 'id', type: 'int'},
    {name: 'name', type: 'string'}, 
    {name: 'address_id', type: 'int'}
],
proxy: {
    type: 'ajax',
    api: {
      read: 'data/persons.json'
    },
    reader: { 
        type: 'json',
        root: 'children',
        successProperty: 'success'
    }
},  
associations: [
    { 
        type: 'hasOne', 
        model: 'Aap.model.Address'
    }
]

});

Ext.define('Aap.model.Address', {
extend: 'Ext.data.Model',
fields: [
    { name: 'id', type: 'int'},
    { name: 'city', type: 'string'}
],
proxy: {
    type: 'ajax',
    api: {
      read: 'data/addresses.json'
    },
    reader: { 
        type: 'json',
        root: 'children',
        successProperty: 'success'
    }
}   

});

Ext.define('Aap.store.Persons', {
extend: 'Ext.data.Store',
model: 'Aap.model.Person',
autoLoad: 'true',
storeId: 'persons'

});

Ext.define('Aap.store.Addresses', {
extend: 'Ext.data.Store',
model: 'Aap.model.Address',
autoLoad: 'true',
storeId: 'addresses'

});

{
"success": true,
"children": [
    { 
        "id": 1,
        "name": "Bernt",
        "address_id": 1
    },
    { 
        "id": 2,
        "name": "Ludowid",
        "address_id": 2
    }
]

}

{
"success": true,
"children": [
    { 
        "id": 1,
        "city": "Berlin"
    },
    { 
        "id": 2,
        "city": "London"
    }
]

}

I don not know where the problem lies.

  • Is it the model that is not correctly defined?
  • Is there a problem with the data
  • Is it the model that is not correctly defined?
  • Or is it something completely different?

Blog entries such as: ExtJS 4: Models with Associations and Stores gave me a better understanding of how associations work. But they did'nt help me to solve the problem.

Thanks for help!

1

1 Answers

0
votes

The generated getter should be used asynchronously, you can't rely on the actual return value.

// Don't do that
var unreliableResult = m.getAllgemein();

// Do that instead
m.getAllgemein(function(allgemeinRecord) {
    // continue from here...
});

See the part named "Generated getter and setter" in the doc for more information.

Be warned however that the callback implementation seems a bit buggy.

Now, regarding the "wrong" data aspect of your question, your associations configuration seems correct to me. I quickly tested your code, and the correct request (that is, with the correct id for the associated record) was fired... So maybe you should elaborate why you think the data is "wrong", and someone may find the mistake then.