Results 1 to 4 of 4

Thread: hasMany will not autoload a relation in time to display with a DataView

    Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1

    Default hasMany will not autoload a relation in time to display with a DataView

    REQUIRED INFORMATION

    Ext version tested:
    • Ext 4.1 rev 1683
    • Sencha Touch 2.0.1.1
    Browser versions tested against:
    • Chrome 19.0.1084.54
    • Safari 5.1.7 (6534.57.2)
    • Safari (iOS 5.1)
    DOCTYPE tested against:
    • HTML5
    Description:
    • I've set the view up to have a DataView that loads data from a Store; the store returns a description of a group of items and the template loops through its hasMany relation (autoLoad: true). When the hasMany relation is queried it is always empty, even though the XHR request has been made to appropriately load the children. Querying the store directly via console reveals all items.
    • All requests are via an Ajax proxy to a PHP script.
    Steps to reproduce the problem:
    • Make two models, Group and Child; both have a title property.
    • Group should associate via hasMany with Child, autoLoad should be true.
    • Proxy configuration should be configured on both models to make an Ajax request to the server.
    • Set up a basic store to grab the Group model.
    • Implement a DataView that connects with the store, that uses an itemTpl like
      Code:
      '{title}: <tpl for="children">{title}, </tpl>'
    The result that was expected:
    • There should be a Group displayed with Children following.
    The result that occurs instead:
    • No children are displayed.
    Test Case:


    Code:
    Ext.define("App.model.Group", {
      extend: 'Ext.data.Model',
    
      config: {
        hasMany: [
          { associatedModel: "App.model.Child", getterName: 'children', autoLoad: true }
        ],
    
        fields: [
          { name: 'id',    type: 'auto' },
          { name: 'title', type: 'string' }
        ],
        
        proxy: {
          type: 'ajax',
          url: 'http://localhost/app/group.php',
          reader: 'json'
        }
      }
    });
    
    Ext.define('App.model.Child', {
      extend: 'Ext.data.Model',
    
      config: {
        fields: [
          { name: 'id', type: 'auto' },
          { name: 'group_id', type: 'auto' },
          { name: 'title', type: 'string' }
        ],
    
        proxy: {
          type: 'ajax',
          url: 'http://localhost/app/child.php',
          reader: 'json'
        }
      }
    });
    
    Ext.define('App.store.Groups', {
      extend: 'Ext.data.Store',
    
      config: {
        model: 'App.model.Group',
        sorters: "title",
        autoLoad: true,
      }
    });
    
    Ext.define("Exhibit.view.Main", {
      extend: 'Ext.Panel',
      requires: [ 'Ext.dataview.Dataview' ],
      items: [
        {
          xtype: 'dataview',
          store: 'Groups',
          itemTpl: '{title}: <tpl for="children">{title}, </tpl><br/>'
        }
      ]
    });
    
    // json stubs
    
    [
    {
      "id": 1,
      "title": "Group 1"
    },
    {
      "id": 2,
      "title": "Group 2"
    },
    ]
    
    [
    {
      "id": 1,
      "group_id": 1,
      "title": "Child 1"
    },
    {
      "id": 2,
      "group_id": 2,
      "title": "Child 2"
    },
    {
      "id": 3,
      "group_id": 1,
      "title": "Child 3"
    },
    {
      "id": 4,
      "group_id": 2,
      "title": "Child 4"
    },
    ]

    HELPFUL INFORMATION
    Debugging already done:
    • none
    Possible fix:
    • This issue can be worked around by nesting the data within the Group results.
    Additional CSS used:
    • none
    Operating System:
    • Mac OS X 10.6.8
    • iOS 5.1

  2. #2
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    40,449

    Default

    Loading is async so the data needs to be present before you try to use it in a dataview.
    Mitchell Simoens @LikelyMitch
    Modus Create, Senior Fullstack Engineer
    ________________
    Modus Create is based on the model of an open source team. We’re a remote, global team of experts in our field. To find out more about the work we do, head over to our website.

    Check out my GitHub:
    https://github.com/mitchellsimoens

  3. #3

    Default

    I've been back and forth between writing this response and the documentation for the last hour and a half. I would like a guide for how to deal with more complex associations, association auto loading, and how to tell if a store has completed loading of all these; the current association guides seem slightly out of date.

    I did look at the DataView class. And since my post, I've hit a situation where the association won't autoload even when that option is set. It appears that when the initial data is loaded the DataView then fires its doRefresh callback. The request for the children is either pending and the DataView doesn't know to wait, or the request hasn't been made and the DataView doesn't know to make it. Then if the children have loaded the DataView doesn't even know to refresh. Looks like loading data and relying on an association getting loaded correctly to render the data, won't fit my need to use a DataView.

    And I think that the number of requests we would get because data is split like this would exceed its convenience. So I'll just make extra queries on the server side to build the nested data structure instead.

  4. #4

    Default HasMany autoLoad callback

    Hi,

    I'm programming using hasMany associations and i think callback function could be helpful in many cases.

    Use case:
    (model "Restaurant" with hasMany association to model "Menu")

    Code:
    Ext.getStore("restaurant").findRecord("Id", 1).menus(
        function(records, operation, success){
            console.log(records);
            console.log(operation);
            console.log(success);
        }
    );
    To use the code in this way, I had to rewrite hasMany.js file
    (Line 320)

    Code:
    //...
        if (autoLoad) {
            if(typeof callback === "function"){
                record[storeName].load({ callback: callback });
            }else{
                record[storeName].load();
            }
        }
    }else{
        if(typeof callback === "function"){
            callback(record[storeName].getData().items, null, true);
        }
    }
    //...
    Link to rewrited file:
    https://db.tt/wcAuT0YG

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •