user156888
user156888

Reputation:

Extjs binding a form to a model that has associations

I have the following JSON structure:

userAuth
----userAccount -- hasOne
----userAccountDetails -- hasMany

I want to show a form that shows data from userAuth and userAccount and then a grid with a row for each row in userAccountDetails

Here is the code for userAuth model:

Ext.define('xxxx.model.UserAuth', {
    extend: 'Ext.data.Model',

    fields: [
       { name: 'id' },
       { name: 'email' },
       { name: 'userName' },
       { name: 'refIdStr' },
       { name: 'displayName' },
       { name: 'modifiedDate', type: 'date', }
    ],

    requires: [
        'xxxx.model.UserAccount',
        'xxxx.model.UserAuthDetails',
    ],

    hasMany: [
        {
            model: 'xxxx.model.UserAuthDetails',
            name: 'authDetails',
            foreignKey: 'userAuthId',
            associationKey: 'userAuthDetails',

        }
    ],

    hasOne: [
        {
            model: 'xxxx.model.UserAccount',
            name: 'userAcount',
            associationKey: 'userAccount',
            getterName: 'getUserAccount',
            setterName: 'setUserAccount',
        }
    ],

    proxy: {
        type: 'ajax',
        startParam: 'skip',
        limitParam: 'take',
        url: settings.ApiUrl + '/model/UserAuth/?format=json',
        baseParams: {
            skip: '0',
            take: '10',
        },
        reader: {
            type: 'json',
            root: 'results',
            successProperty: 'success',
            totalProperty: 'totalCount'
        }
    }
});

And userAccount model

Ext.define('xxxx.model.UserAccount', {
    extend: 'Ext.data.Model',
    fields: [
       { name: 'username' },
       { name: 'id' },
       { name: 'name' },
       { name: 'email' },
       { name: 'slug' },
       { name: 'facebookId' }
    ],

    belongsTo: 'xxxx.model.UserAuth',

    proxy: {
        type: 'ajax',
        startParam: 'skip',
        limitParam: 'take',
        url: settings.ApiUrl + '/model/UserAccount/?format=json',
        baseParams: {
            skip: '0',
            take: '10',
        },
        reader: {
            type: 'json',
            root: 'results',
            successProperty: 'success',
            totalProperty: 'totalCount'
        }
    }
});

and userAuthDetails:

Ext.define('xxxx.model.UserAuthDetails', {
    extend: 'Ext.data.Model',
    fields: [
       { name: 'id' },
       { name: 'userAuthId' },
       { name: 'provider' },
       { name: 'userId' },
       { name: 'userName' },
       { name: 'displayName' },
       { name: 'firstName' },
       { name: 'lastName' },
       { name: 'email' },
       { name: 'modifiedDate' },
       { name: 'provider' },
    ],

    belongsTo: [
        {
            model: 'xxxx.model.UserAuth',
            isntanceName: 'userAuth',
            getterName: 'getUserAuthDetails',
            setterName: 'setUserAuthDetails',
            associationKey: 'userAuthDetails'
        }
    ],

    proxy: {
        type: 'ajax',
        startParam: 'skip',
        limitParam: 'take',
        url: settings.ApiUrl + '/model/UserAuthDetails/?format=json',
        baseParams: {
            skip: '0',
            take: '10',
        },
        reader: {
            type: 'json',
            root: 'results',
            successProperty: 'success',
            totalProperty: 'totalCount'
        }
    }
});

Loading the store works and the associations work - when i call record.getUserAccount().get('email') it returns what I'd expect - so all that is working.

Now, my question is - how the hell do i get that data into the form described above?

I have tried doing things like:

{
    xtype: 'textfield',
    fieldLabel: 'username',
    allowBlank: false,
    maxLength: 100,
    name: 'userAccount.userName'
}

thinking the association name might be a good hint for it - but that doesn't work...

Data from the top most model (userAuth) works ok - I just can't seem to pull in the hasOne into the form.

I haven't even tried binding the userAuthDetails to a grid yet but suspect that will be equally as challenging

Has anyone managed to get this to work? I only went down the associations route because i thought it would make this sort of stuff cleaner / simpler!

[EDIT]

Giving up trying to do this with a form as I am happy for this data to be read only for now. I am now trying to show this data in an xtemplate within a row expander.

I've tried the following but it does not work!!!

plugins: [
    {
        ptype: 'rowexpander',
        rowBodyTpl: [
            '<p><b>Username:</b> {userName}</p>',
            '<p><b>Email:</b> {userAccount.email}</p>',
            '<tpl for="userAuthDetails">',
                 '<p>{provider}</p>',
            '</tpl>'
        ]
    }],

What sort of voodoo do I need to make this work? It is not obvious at all!!!

ATM I am thinking I won't be using ExtJs again - I've found myself in too many dark holes like this recently where things blatantly should just work the way you'd expect - just googling this shows everyone expects this to work. I've used ExtJs on and off for years but I think now is the time to finally admit there are better js application frameworks out there.

Upvotes: 0

Views: 2739

Answers (1)

Saki
Saki

Reputation: 5856

Unfortunately, there is no automatic, config-only way of how to do that. If you look at the loadRecord source you see that it just gets data from the passed record and calls setValues on the form.

You would need to override loadRecord method to dig the required values from the associated record(s).

Upvotes: 1

Related Questions