View Full Version : Problem loading custom views in my viewport

19 Nov 2011, 10:40 PM

I'm trying to create a MVC application and I defined some new view.

A grid
A panel for detail of the selected item in grid
and a master panel containing the grid in the north region, and the detail panel in the south region.

In my Application.js file, I try to create my view.Viewport class.

Code of Grid.js

Ext.define('ElementsPMI.view.knowledgearea.Grid', {
extend: 'Ext.grid.Panel',

alias: 'widget.knowledgeareagrid',

// override
initComponent : function() {
// Pass in a column model definition
this.columns = [
{text: "ID", width: 20, dataIndex: 'id', sortable: true},
{text: "Name", width: 100, dataIndex: 'name', sortable: true},
{text: "Description", width: 100, dataIndex: 'description', sortable: true},
{text: "Type", width: 100, dataIndex: 'type', sortable: true, groupable: true}

// Note the use of a storeId, this will register thisStore
// with the StoreManager and allow us to retrieve it very easily.
this.store = new ElementsPMI.store.KnowledgeAreaStore({
storeId: 'gridKnowledgeAreaStore',

// finally call the superclasses implementation

Code of DetailPanel.js

Ext.define('ElementsPMI.view.knowledgearea.DetailPanel', {
extend: 'Ext.Panel',

// register the ElementsPMI.view.knowledgearea.DetailPanel class with an xtype of knowledgeareadetailpanel
alias: 'widget.knowledgeareadetailpanel',

// add tplMarkup as a new property
tplMarkup: [
'ID: <a href="{DetailPageURL}" target="_blank">{ID}</a><br/>',
'Name: {Author}<br/>',
'Description: {Description}<br/>',
'Type: {Type}<br/>'
// startingMarup as a new property
startingMarkup: 'Please select a knowledge area to see additional details',

bodyPadding: 7,
// override initComponent to create and compile the template
// apply styles to the body of the panel and initialize
// html to startingMarkup
initComponent: function() {
this.tpl = Ext.create('Ext.Template', this.tplMarkup);
this.html = this.startingMarkup;

this.bodyStyle = {
background: '#ffffff'
// call the superclass's initComponent implementation
// add a method which updates the details
updateDetail: function(data) {
this.tpl.overwrite(this.body, data);

Code of MasterPanel.js

Ext.define('ElementsPMI.view.knowledgearea.MasterPanel', {
extend: 'Ext.Panel',

alias: 'widget.knowledgeareamasterpanel',

frame: true,
title: 'Knowledge Area List',
width: 540,
height: 400,
layout: 'border',

// override initComponent
initComponent: function() {
this.items = [{
xtype: 'knowledgeareagrid',
itemId: 'gridPanel',
region: 'north',
height: 210,
split: true
xtype: 'knowledgeareadetailpanel',
itemId: 'detailPanel',
region: 'center'
// call the superclass's initComponent implementation
// override initEvents
initEvents: function() {
// call the superclass's initEvents implementation

// now add application specific events
// notice we use the selectionmodel's rowselect event rather
// than a click event from the grid to provide key navigation
// as well as mouse navigation
var knowledgeareaGridSm = this.getComponent('gridPanel').getSelectionModel();
('selectionchange', function(sm, rs) {
if (rs.length) {
var detailPanel = Ext.getCmp('detailPanel');
knowledgeareaTpl.overwrite(detailPanel.body, rs[0].data);
knowledgeareaGridSm.on('selectionchange', this.onRowSelect, this);
// add a method called onRowSelect
// This matches the method signature as defined by the 'rowselect'
// event defined in Ext.selection.RowModel
onRowSelect: function(sm, rs) {
// getComponent will retrieve itemId's or id's. Note that itemId's
// are scoped locally to this instance of a component to avoid
// conflicts with the ComponentManager
if (rs.length) {
var detailPanel = this.getComponent('detailPanel');


Code of the viewport (only the 'center' region). It works if I switch 'knowledgeareamasterpanel' for 'panel', so it really is something with my code, not the viewport definition.

region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title
activeTab: 0, // First tab active by default
bodyPadding: 5,
items: [{
title: 'Home',
html: 'The first tab\'s content. Others may be added dynamically'
}, {
title: 'Knowledge Areas',
xtype: 'knowledgeareamasterpanel',
closable: true

I get the error

namespace is undefinedchrome://firebug/content/blank.gif if (namespace === from...substring(0, from.length) === from)

From what I read on the forum, people were saying I need to use 'widget' in the alias, but I was already doing this.

Any help would be greatly appreciated!

20 Nov 2011, 7:05 AM
I realize I didn't put the Application.js code.

Here it is

enabled: true

name: 'ElementsPMI',
appFolder: 'app',
views: ['knowledgearea.Grid', 'knowledgearea.DetailPanel', 'knowledgearea.MasterPanel', 'Viewport'],
launch: function() {
Ext.create('ElementsPMI.view.Viewport', {});

20 Nov 2011, 12:07 PM
Except from the xtype you mention yourself there are also some others add to the items of that particular class in its initComponent. So it might be that the problem is there.

However, I think it is this: Since you are using dynamic loading all classes get loaded (defined) after the containing file is pulled in. So your xtype aliasses are registered only when that file is pulled in. So now you are instantiateding by xtype and the classfile is not pulled in yet, therefore the xtype is not defined yet and therefore you get this exception. If you want to use dynamic loading you will need to add requires properties for the classes you want to dynamically load.

20 Nov 2011, 5:57 PM
That fixed it, along with a few typos I discovered in the process.

I also discovered I need to fully qualify my class name when creating a new instance of a store. so in my grid, I had to use ElementsPMI.store.KnowledgeAreaStore();

I guess I will try to find an article/tutorial about the best way to load classes. Should I always use the requires property? or is there a better way?


20 Nov 2011, 10:55 PM
Personally I don't work with the loader. We have an custom tool that builds our websites (combine different sources/features, bundling files, minifying and shiit all onFileChange) So maybe others might know better.

However, as far as I know, requires is the way to go for dynamic loading (and later on building one app.js)