I'm trying to define a Tree panel at the moment, with the backend as a CouchDB database.

The "design model" of the tree is that of an company.

The top of the tree always a type "organisation", this is a parent record that is used for the name and other details. When loading the tree the parent_id is set as "root", so by setting rootVisible to false, the top of the tree panel will always been this organisation.

Then under this, there can be "departments", "locations" and "roles", each of these have a parent_id property too which will always be the _id of the parent item.

The TreeStore is defined as this:

Code:
/*
Organisation store
*/Ext.define('QM.store.Organisation', {
  extend: 'Ext.data.TreeStore',
  model: 'Organisation',
  storeId: 'Organisation',
  fields: ['_id', 'name', 'type'],
  autoLoad: true,
  autoSync: true,
  nodeParam: 'key',
  proxy: {
    type: 'dnode',
    DNodeFN: RPC.session.getTree,
    extraParams: {
      type: "organisation",
      list: "organisation/treegrid/treegrid",
      couchOptions: {
        include_docs: true
      }
    }
  },
  root: {
    id: 'root',
    name: '.'
  },
  listeners: {
    load: function() {
      return console.log(arguments);
    }
  }
});
Based on this, the panel correctly loads the "organisation" type at the top of the tree. However, when I try to expand the tree it does not load the child elements. The nodeParam of 'key' always gets sent as an empty string because it seems to ignore that I want to read _id instead of id.

The model itself that is used is quite simple, because the tree is never used as a way to edit each element, they each have their own model and forms - but everything is based on a base model type for CouchDB that has it's idProperty set, but this seems to be ignored:

Code:
Ext.define('QM.model.Organisation', {
  extend: 'QM.model.Base',
  fields: [
    {
      name: 'name',
      type: 'string'
    }
  ],
  validations: [
    {
      type: 'presence',
      field: 'name'
    }
  ]
});
Code:
Ext.define('QM.model.Base', {
  extend: 'Ext.data.Model',
  requires: ['QM.data.DNodeProxy'],
  idProperty: '_id',
  constructor: function() {
    this.callParent(arguments);
    if (!this.get(this.idProperty)) {
      this.set(this.idProperty, '');
    }
    if (!this.get('_rev')) {
      this.set('_rev', '');
    }
    if (!this.get('_attachments')) {
      this.set('_attachments', '');
    }
    if (!this.get('available')) {
      this.set('available', true);
    }
    if (!this.get('status')) {
      return this.set('status', 'None');
    }
  },
  fields: [
    {
      name: '_id',
      type: 'string'
    }, {
      name: '_rev',
      type: 'string'
    }, {
      name: '_attachments'
    }, {
      name: 'type',
      type: 'string'
    }, {
      name: 'created',
      type: 'date'
    }, {
      name: 'modified',
      type: 'date'
    }, {
      name: 'parent_id',
      type: 'string'
    }, {
      name: 'available',
      type: 'boolean'
    }, {
      name: 'status',
      type: 'string'
    }
  ],
  proxy: {
    type: 'dnode',
    api: {
      read: RPC.session.getDoc,
      create: RPC.session.createDoc,
      update: RPC.session.updateDoc,
      destroy: RPC.session.deleteDoc
    },
    baseParams: {
      include_docs: true
    }
  }
});
For completness, here is the TreePanel that is defined:

Code:
Ext.define('QM.view.organisation.Tree', {
  extend: 'Ext.window.Window',
  alias: 'widget.orgtree',
  require: ['Ext.direct.*', 'Ext.data.*', 'Ext.tree.*', 'Ext.grid.Scroller', 'QM.view.organisation.ContextMenu'],
  title: 'Your Organisation',
  layout: 'fit',
  width: 960,
  height: 400,
  initComponent: function() {
    Ext.apply(this, {
      items: [
        {
          xtype: 'treepanel',
          useArrows: true,
          rootVisible: false,
          multiSelect: true,
          singleExpand: true,
          hideHeaders: false,
          store: Ext.getStore('Organisation'),
          columns: [
            {
              xtype: 'treecolumn',
              text: 'Name',
              flex: 2,
              sortable: false,
              dataIndex: 'name'
            }, {
              text: 'Type',
              flex: 1,
              sortable: false,
              dataIndex: 'type'
            }
          ],
          listeners: {
            itemcontextmenu: function(view, record, item, index, event) {
              record.menu = Ext.create('QM.view.organisation.ContextMenu');
              record.menu.showAt(event.getXY());
              return event.stopEvent();
            }
          }
        }
      ]
    });
    this.callParent(arguments);
  }
});
Does anyone know a way to get this working correctly?