Thank you for reporting this bug. We will make it our priority to review this report.
  1. #11
    Ext GWT Premium Member
    Join Date
    Oct 2009
    Posts
    10
    Vote Rating
    2
    Tom Haller is on a distinguished road

      0  

    Default


    One last thought - you might actually want a REST or AJAX proxy on the child if it's possible to retrieve the child independently of the parent - e.g. all addresses, not just one person's address. You can do this with HasMany - if the children are already populated when the data is retrieved, the proxy isn't used, but you can retrieve the child model outside of the parent using the child's proxy.

  2. #12
    Ext GWT Premium Member
    Join Date
    Oct 2009
    Posts
    10
    Vote Rating
    2
    Tom Haller is on a distinguished road

      0  

    Default


    P.S.: I tried setting instanceName in the HasOne config (though it's not documented); it does work, but HasOne is apparently hard-wired to find the child data based on the child's class name, so every HasOne pointing to the same model returns the same instance.

  3. #13
    Ext GWT Premium Member
    Join Date
    Oct 2009
    Posts
    10
    Vote Rating
    2
    Tom Haller is on a distinguished road

      2  

    Lightbulb Finally, a totally working sane example of HasOne

    Finally, a totally working sane example of HasOne


    Hi all, I'm the original poster and finally getting back to this... after calming down and working through this methodically for a day, I came up with a snippet which demonstrates everything I was trying to do:
    • One-to-one associations (one instance of one model contains one instance of another);
    • Prepopulated object graph (server returns complete JSON, no extra fetches to get children);
    • One class can be contained more than once (e.g. work address, home address);
    • Complex class names used (i.e. with dots in them);
    • Simple getter/setter name, i.e. no dots in the names, so no "obj['my.fun'].call(this)".
    It all seems to work, so I withdraw my original complaint about the constructor not working. However this relies on some undocumented config members, and the API could have been friendlier (and documented! the docs have the simplest possible example which isn't very useful).

    Here's the example (supply your own index.html or whatever to drive it):

    Code:
    // Contained model.
    Ext.define('My.Address', {
        extend: 'Ext.data.Model',
        fields: [ 'street', 'city' ]
    });
     
    // Containing model.
    Ext.define('My.Person', {
        extend: 'Ext.data.Model',
        fields: [ 'id', 'name' ],
        associations: [{
            type: 'hasOne',
            model: 'My.Address',
            associationKey: 'work', // name of node to read from data
            name: 'work', // name of node to create in data (getData(true))
            instanceName: 'workInstance', // allow multiple instances of same class
            getterName: 'getWork', // avoid dots in function name
            setterName: 'setWork' // avoid dots in function name
        }, {
            type: 'hasOne',
            model: 'My.Address',
            associationKey: 'home',
            name: 'home',
            instanceName: 'homeInstance',
            getterName: 'getHome',
            setterName: 'setHome'
        }],
        proxy: {
            type: 'memory',
            data: {
                success: true,
                user: {
                   id: 1,
                   name: 'Mickey Mouse',
                   work: {
                       street: 'Main Street',
                       city: 'Anytown'
                   },
                   home: {
                       street: 'Elm Street',
                       city: 'Halloween Town'
                   }
                }
            },
            reader: {
                type: 'json',
                root: 'user',
                successProperty: 'success'
            }
        }
    });
    
    
    Ext.create('Ext.app.Application', {
        name: 'My',
    
    
        launch: function () {
            My.Person.load(1, {
                success: function (person) {
                    var addr;
    
    
                    console.log('person:');
                    console.log('  id   = ' + person.get('id'));
                    console.log('  name = ' + person.get('name'));
     
                    addr = person.getWork();
     
                    console.log('  Work address:');
                    console.log('    street = ' + addr.get('street'));
                    console.log('    city   = ' + addr.get('city'));
    
    
                    addr = person.getHome();
     
                    console.log('  Home address:');
                    console.log('    street = ' + addr.get('street'));
                    console.log('    city   = ' + addr.get('city'));
                }
            });
        }
    });
    Here is the output of the above:

    Code:
    
    person:
      id   = 1
      name = Mickey Mouse
      Work address:
        street = Main Street
        city   = Anytown
      Home address:
        street = Elm Street
        city   = Halloween Town
    
    Executing person.getData(true) will give you plain javascript object which faithfully duplicates the structure of the original source (though field order may change). If you have a server which provides a complete object graph for a GET, then allows you to send the same complex structure back for update (PUT), you are good to go.

  4. #14
    Sencha Premium Member
    Join Date
    Nov 2010
    Posts
    21
    Vote Rating
    1
    JBlinten is on a distinguished road

      0  

    Default


    Tom,

    Many thanks for posting this clear example. It demonstrates a solution to a model problem I have been struggling with for a while. Given the state of Sencha documentation, I would have never figured it out on my own.

    It seems that modelling simple nested data structures is a very common situation. I am surprised that it has taken until 4.1 to handle this. I guess the approach has been to mod it "on the server" until now.

  5. #15
    Ext GWT Premium Member
    Join Date
    Oct 2009
    Posts
    10
    Vote Rating
    2
    Tom Haller is on a distinguished road

      0  

    Default


    You are most welcome. This was really driving me nuts until I figured it out, and I am really glad the solution was useful to someone else. I'm a little nervous about relying on undocumented config properties, however, so if you use this do be careful to retest after Ext upgrades.

    Quote Originally Posted by JBlinten View Post
    Tom,

    Many thanks for posting this clear example. It demonstrates a solution to a model problem I have been struggling with for a while. Given the state of Sencha documentation, I would have never figured it out on my own.

    It seems that modelling simple nested data structures is a very common situation. I am surprised that it has taken until 4.1 to handle this. I guess the approach has been to mod it "on the server" until now.

  6. #16
    Sencha User
    Join Date
    Jun 2012
    Posts
    1
    Vote Rating
    0
    xeanliao is on a distinguished road

      0  

    Default


    I have been struggling whole day trying to figure out why getter/setting not generated. Really appreciate this sample. but I am still having problem to access the hasOne-associated object.

    Here is my console output:

    person: app.js:41
    id = 1 app.js:42
    name = Mickey Mouse app.js:43
    • [COLOR=red !important]Uncaught TypeError: Object [object Object] has no method 'getWork' app.js:45[/COLOR]


    Any clue? I started wondering whether there is a bug on the SDK version I am using?

    C:\Users\Sean\Desktop\sencha-touch-2.0.1.1>sencha
    Sencha Command v2.0.2
    Copyright (c) 2012 Sencha Inc.




    Quote Originally Posted by Tom Haller View Post
    Hi all, I'm the original poster and finally getting back to this... after calming down and working through this methodically for a day, I came up with a snippet which demonstrates everything I was trying to do:
    • One-to-one associations (one instance of one model contains one instance of another);
    • Prepopulated object graph (server returns complete JSON, no extra fetches to get children);
    • One class can be contained more than once (e.g. work address, home address);
    • Complex class names used (i.e. with dots in them);
    • Simple getter/setter name, i.e. no dots in the names, so no "obj['my.fun'].call(this)".
    It all seems to work, so I withdraw my original complaint about the constructor not working. However this relies on some undocumented config members, and the API could have been friendlier (and documented! the docs have the simplest possible example which isn't very useful).

    Here's the example (supply your own index.html or whatever to drive it):

    Code:
    // Contained model.
    Ext.define('My.Address', {
        extend: 'Ext.data.Model',
        fields: [ 'street', 'city' ]
    });
     
    // Containing model.
    Ext.define('My.Person', {
        extend: 'Ext.data.Model',
        fields: [ 'id', 'name' ],
        associations: [{
            type: 'hasOne',
            model: 'My.Address',
            associationKey: 'work', // name of node to read from data
            name: 'work', // name of node to create in data (getData(true))
            instanceName: 'workInstance', // allow multiple instances of same class
            getterName: 'getWork', // avoid dots in function name
            setterName: 'setWork' // avoid dots in function name
        }, {
            type: 'hasOne',
            model: 'My.Address',
            associationKey: 'home',
            name: 'home',
            instanceName: 'homeInstance',
            getterName: 'getHome',
            setterName: 'setHome'
        }],
        proxy: {
            type: 'memory',
            data: {
                success: true,
                user: {
                   id: 1,
                   name: 'Mickey Mouse',
                   work: {
                       street: 'Main Street',
                       city: 'Anytown'
                   },
                   home: {
                       street: 'Elm Street',
                       city: 'Halloween Town'
                   }
                }
            },
            reader: {
                type: 'json',
                root: 'user',
                successProperty: 'success'
            }
        }
    });
    
    
    Ext.create('Ext.app.Application', {
        name: 'My',
    
    
        launch: function () {
            My.Person.load(1, {
                success: function (person) {
                    var addr;
    
    
                    console.log('person:');
                    console.log('  id   = ' + person.get('id'));
                    console.log('  name = ' + person.get('name'));
     
                    addr = person.getWork();
     
                    console.log('  Work address:');
                    console.log('    street = ' + addr.get('street'));
                    console.log('    city   = ' + addr.get('city'));
    
    
                    addr = person.getHome();
     
                    console.log('  Home address:');
                    console.log('    street = ' + addr.get('street'));
                    console.log('    city   = ' + addr.get('city'));
                }
            });
        }
    });
    Here is the output of the above:

    Code:
    
    person:
      id   = 1
      name = Mickey Mouse
      Work address:
        street = Main Street
        city   = Anytown
      Home address:
        street = Elm Street
        city   = Halloween Town
    
    Executing person.getData(true) will give you plain javascript object which faithfully duplicates the structure of the original source (though field order may change). If you have a server which provides a complete object graph for a GET, then allows you to send the same complex structure back for update (PUT), you are good to go.

  7. #17
    Ext GWT Premium Member
    Join Date
    Oct 2009
    Posts
    10
    Vote Rating
    2
    Tom Haller is on a distinguished road

      0  

    Default


    Sorry to hear you're having a problem with that. I'm not using Touch and my example is only known to work for Ext JS 4.1.x. You may have tried all of this already, but I would:
    • Step through in a debugger and determine what members are actually created in your objects;
    • Read the source code for Association and HasOne to figure out how members are created;
    • Double-check the documentation.
    That is basically how I figured this out, so it might need to be repeated for Touch which may be implemented differently. Note, I listed the documentation last

  8. #18
    Sencha Premium Member
    Join Date
    May 2012
    Posts
    13
    Vote Rating
    0
    OllieJ is on a distinguished road

      0  

    Default hasOne setter problems

    hasOne setter problems


    Hi All,

    I'm also having trouble with hasOne associations. I have managed to load a store of the parent Person model objects with some already having associated Address objects using nested JSON - this works fine at first load. However I am then trying to assign an Address from a store to a Person object within the application using setAddress(addressRecord).
    This call produces the request to the server with the Person and the updated address_id set.
    The server then returns the Person with the associated Address object nested.

    On inspection the Person model is being updated (tested by returning changed person fields) but the associated address object is still blank.
    Now I have found in the operation.resultSet.records array passed to the callback of the setAddress function I can find a Person record with the associated Address, so I can write:
    Code:
    personRecord.setAddress(addressRecord,{            
                callback: function(personRecord, operation) {},
                success : function(personRecord, operation) {
                    personRecord.address.data = operation.resultSet.records[0].address.data;
                    this.getPersonsStore().fireEvent('refresh',this.getPersonsStore());
                },
                failure : function(personRecord, operation) {},
                scope: this
            });
    I don't believe this what I am supposed to do, so I am just wondering if anybody else has experienced similar issues or has an idea what I may be missing? Is this possibly a bug?

    A related issue here is that the setAddress function is updating the server with the association and also updating the client side Address data from the server is this good practice (for concurrency) or unnecessary traffic if I already have the Address data in a store locally?

    Thanks in advance and apologies if this is a silly question, I am very new to Ext JS.

    Ollie

  9. #19
    Sencha User
    Join Date
    Jul 2011
    Posts
    15
    Vote Rating
    1
    noiks is on a distinguished road

      0  

    Default


    Thanks a lot Tom, posting link of this in documentation.

  10. #20
    Sencha User
    Join Date
    Jul 2013
    Posts
    9
    Vote Rating
    0
    ksonger is on a distinguished road

      0  

    Default


    You are a champion, Tom Haller. Thanks so much for this - I'd been struggling with it for an entire day.

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi