1. #1
    Sencha User
    Join Date
    May 2011
    Posts
    1
    Vote Rating
    0
    hartct is on a distinguished road

      0  

    Default Problem displaying nested model data in Sencha Touch XTemplate

    Problem displaying nested model data in Sencha Touch XTemplate


    I am using Sencha Touch to display nested (associated) model data in a list template but I can only get the root model data to display. My models are an Appointment which belongs to a Customer, and Customers have many Appointments. My model code:

    Code:
    Customer = Ext.regModel('Customer', {
    hasMany: { model: 'Appointments', name: 'appointments' },
    fields: [
      { name: 'id', type: 'integer' },
      { name: 'firstName', type: 'string' },
      { name: 'lastName', type: 'string' },
      { name: 'email', type: 'string' },
      { name: 'secondary_email', type: 'string' },
      { name: 'homePhone', type: 'string' },
      { name: 'mobilePhone', type: 'string' },
      { name: 'dob', type: 'date', dateFormat: 'Y-m-d' },
      { name: 'allowLogin', type: 'boolean' },
      { name: 'emailReminders', type: 'boolean' },
      { name: 'reminders_to_stylist', type: 'boolean' },
      { name: 'fullName',
        convert: function(value, record) {
          var fn = record.get('firstName');
          var ln = record.get('lastName');
          return fn + " " + ln;
        } }
     ]
     });
    
    Appointment = Ext.regModel('Appointment', {
    belongsTo: { model: 'Customer', name: 'customer' },
    fields: [
      { name: 'id', type: 'string' },
      { name: 'startTime', type: 'date', dateFormat: 'c' },
      { name: 'customer_id', type: 'integer' },
      { name: 'startTimeShort',
        convert: function(value, record) {
          return record.get('startTime').shortTime();
        }
      },
      { name: 'endTimeShort',
        convert: function(value, record) {
          return record.get('endTime').shortTime();
        }
      },
      { name: 'endTime', type: 'date', dateFormat: 'c' } 
    ]
    });
    And my panel using an xtype: list looks like:

    Code:
    var jsonPanel = {
    title: "Appointments",
    items: [
      {
        xtype: 'list',
        store: appointmentStore,
        itemTpl: '<tpl for="."><span id="{id}">{startTimeShort} - {endTimeShort} <tpl for="customer"><span class="customer">{firstName}</span></tpl></span></tpl>',
        singleSelect: true,
        onItemDisclosure: function(record, btn, index) {
          Ext.Msg.alert('test');
        }
      }
    ]
    };
    The nested data gets loaded from JSON and appears to be loading correctly into the store - when I debug the appointment store object loaded from the Appointment model, I see that the appointment.data.items array objects have a CustomerBelongsToInstance object and that object's data object does contain the correct model data. The startTime and endTime fields display correctly in the list.

    I have a suspicion that I am either not using the item template markup correctly, or perhaps there is some weird dependency where I would have to start from the model that has the "has many" association rather than the "belongs to" as shown in the kitchen sink demo.

    I wasn't able to find any examples that used this type of association so any help is appreciated.

  2. #2
    Sencha User
    Join Date
    Jun 2011
    Location
    Columbia, MO
    Posts
    1
    Vote Rating
    0
    timg73 is on a distinguished road

      0  

    Default


    I just had this same issue, and the following worked for my needs.

    You might try overriding the prepareData function for your List in your items config object:

    Code:
    prepareData: function(data, index, record) { return data; }
    If your nested model is loaded with all the associated data already, and each nested model does not have a data store associated with it, then the default implementation of prepareData will overwrite the nested array data with empty arrays as it tries to retrieve the data from each store (which do not exist). The solution above simply returns the data as already having been prepared with the nested data.

    You can take a look at the default implementation of prepareData, it is defined in the DataView object.

    Once you override prepareData, your template should work as is.

    Hope this helps!

  3. #3
    Sencha User
    Join Date
    Aug 2011
    Posts
    17
    Vote Rating
    0
    beetree is on a distinguished road

      0  

    Default


    Here is another attempt at fixing the bug: http://www.sencha.com/forum/showthread.php?127659-prepareData-in-DataView-should-not-override-Record-data

    Actually, let me correct that. It seems that you need both these solutions to fully fix the problem. Here is what I ended up adding to my code to solve it:

    Code:
    Ext.override(Ext.DataView, {
        collectData : function(records, startIndex){
            var r = [],
                i = 0,
                len = records.length;
    
    
            for(; i < len; i++){
                r[r.length] = this.prepareData(Ext.apply({}, records[i].data), startIndex + i, records[i]);
            }
    
    
            return r;
        }
    });
    
    Ext.override(Ext.List, {
        prepareData: function(data, index, record){
            return data;
        }
    });

Thread Participants: 2

Tags for this Thread