I've started a project with sencha touch (my first real experience with JS), and I'm afraid I've bitten off more than I can chew..
I've created most of my app but I'm having a problem trying to put a Nested list inside of a tab panel. I get this error:
Uncaught TypeError: Cannot call method 'getRootNode' of undefined.
And here's how I'm trying to insert it:
{
title: 'Settings',
iconCls: 'settings',
layout: 'card',
items: [nestedPanel]
}
Can someone point me in the right direction?
Your code should be something like :
App.views.MyNestedList = Ext.extend(Ext.NestedList, {
iconCls : '',
iconMask : true,
title : '',
store : '',
itemTpl : '',
});
Ext.reg('MyNestedList', App.views.MyNestedList);
App.views.myTabs = Ext.extend(Ext.TabPanel,{
items : [
{xtype : 'MyNestedList'}
]
});
Related
I created this fiddle showing what I want to do.
Basically, I configured a Store that loads only a single record (it reality it will be the currently signed in user). However, I can't seem to bind anything to that store properly. How can I get that {u.name} to output properly?
Here is the code:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name']
});
Ext.application({
name : 'Fiddle',
launch : function() {
new Ext.Component({
renderTo: Ext.getBody(),
viewModel: {
stores: {
u: {
proxy: {
type: 'ajax',
url: 'user.json'
},
model: 'User',
autoLoad: true
}
}
},
bind: 'Test name: {u.name}'
});
}
});
Try bind: 'Test name: {u.data.items.0.name}'
UPD:
As an explanation to this - u is an object with its properties, so trying to bind to u.name will actually bind to the name property of the store. Wile the store has no name property it will always be null. Store's received data is placed in data property. Items property contains a raw array of received data and so on.
In your fiddle you're using a store while it looks like you need just a single record.
Using links instead of stores should work better, like:
links: {
u: {
type: 'User',
id: 1
}
}
Working example based on your code: https://fiddle.sencha.com/#fiddle/uuh
I am new to Extjs. I am trying to destroy my component.
To achieve this, I am trying to pass my component name using the getCmp method.I am unsure how to pass the id.
This is my component id -
Ext.tab.Panel{itemId: "sportsSeenTabPanels", id:"panel-117"}
providing my code below
if (ball.Desktop.isConfigured()) {
ball.Desktop.onMainContentDestroy(function() {
Ext.getCmp('id').destroy();
});
}
The following is the error I receive -
Uncaught TypeError: Cannot read property 'destroy' of undefined
if you make a component/panel like this :
Ext.create('Ext.panel',{
title: 'panel Parent',
id: 'parentID',
items: [
{
xtype: 'panel',
title: 'child panel',
id: 'childID',
itemId: 'childItemID'
}
]
});
you can select component using :
Ext.getCmp('childID') or Ext.getCmp('parentID').down('#childItemID');
As S Rifai suggested, you should use the relatively new EXT JS syntax for your components (introduced in the version 4,5 and 6) rather than the EXT JS 3 syntax.
Nonetheless Ext.getCmp('myComponentId').destroy(); works. You made a typo in your code at this line :
Ext.getCmp('id').destroy();
'id' is the name of the tag, replace it with its value : 'panel-117'
Ext.getCmp('panel-117').destroy();
I created a sample TreePanel using Sencha ExtJs 5.
I followed the sample example in the documentations and I am able to see the items (leaves and branches) but they are not coming as a Tree, but as a list.
Here is my code:
Store:
Ext.define('MyApp.store.ResourcesStore', {
extend : 'Ext.data.TreeStore',
root : {
expanded : true,
children : [ {
text : "UI Forms",
leaf: false,
expanded : true,
children : [ {
text : "Web",
leaf : true
}, {
text : "Smart Phone",
leaf : true
}, {
text : "Tablet",
leaf : true
}, ]
}, {
text : "Reports",
leaf : true
}, {
text : "Dashboards",
leaf : true
}, {
text : "Entities",
leaf : true
}, {
text : "Queries",
leaf : true
}, {
text : "Services",
leaf : true
} ]
}
});
View:
Ext.define('MyApp.view.leftpanel.ResourcesView', {
extend : 'Ext.TreePanel',
xtype : 'resources-panel',
title : 'Resources',
store : 'ResourcesStore',
rootVisible : false
});
Here is what my output looks like:
After executing the sencha app build command:
Accordion panel got impacted.
If you use Sencha Cmd then you most likely need to:
sencha app refresh
sencha ant sass
and if it does not help then
sencha app build
Application bootstrap needs to know that you are using trees so it knows which css to load.
I had similar problem and found that just stopping "Sencha app watch" and restarting it resolved it.
Me too,the icons do not show,it looks like a list.And in my case, the sencha app build does not work. But I used sencha app watch,and the icons come around.I guess there must be something wrong with the the sencha cmd of my version 'Sencha Cmd v5.1.2.52',the watch cmd works is due to it helps to add the sass I needed.
I would like to send data with setActiveItem() when doing view change from this store:
Ext.define('SkSe.store.Places',{
extend:'Ext.data.Store',
config:{
autoDestroy: true,
model:'SkSe.model.Places',
//hardcoded data
data: [
{
name: 'Caffe Bar XS', //naziv objekta
icon: 'Icon.png', //tu bi trebala ići ikona kategorije kojoj pripada
stamps: 'stamps1' //broj "stampova" koje je korisnik prikupio
},
{
name: 'Caffe Bar Mali medo',
icon: 'Icon.png',
stamps: 'stamps2'
},
{
name: 'Caffe Bar VIP',
icon: 'Icon.png',
stamps: 'stamps3'
}
]
//dynamic data (Matija)
//remember to change the icon path in "Akcije.js -> itemTpl"
/*proxy:{
type:'ajax',
url:'https://maps.googleapis.com/maps/api/place/search/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AIzaSyCFWZSKDslql5GZR0OJlVcgoQJP1UKgZ5U',
reader:{
type:'json',
//name of array where the results are stored
rootProperty:'results'
}
}*/
}
});
This is my my details controller that should get data from places store:
Ext.define('SkSe.controller.Details', {
extend: 'Ext.app.Controller',
config: {
refs: {
placesContainer:'placesContainer',
Details: 'details'
},
control: {
//get me the list inside the places which is inside placesContainer
'placesContainer places list':{
itemsingletap:'onItemTap'
//itemtap:'onItemTap'
}
}
},
onItemTap:function(list,index,target,record){
console.log('omg');
var addcontact= Ext.create('SkSe.view.Details',
{
xtype:'details',
title:record.data.name,
data:record.data
});
var panelsArray = Ext.ComponentQuery.query('details');
console.log(panelsArray);
Ext.Viewport.add(addcontact);
addcontact.update(record.data.name);
Ext.Viewport.setActiveItem(addcontact);
console.log(record.data.name);
}
});
I would like to send name record from the places.js model above. I heard that you can't pass data with setActiveItem but should create a function that updates view(No I can't use pop and push here).
I'm not very familiar with sencha touch syntax and I'm not sure what functions to use to do that, clearly update function is not that.
I switched up your logic slightly but have provided a working example of what I think you are trying to do.
SenchaFiddle is a little different from what I get running on my machine but you should be able to get the idea.
The initial list loaded gets the data from your store, and on itemtap will push a new view onto the viewport.
You will need to add a navigation button to get back to the list from view.View as well as a better layout for the details. I would suggest nested containers or panels with custom styles to get the details just right. Alternatively you can just drop a full html snippet in there with all the data laid out like you want.
Would be happy to help more.
Fiddle: http://www.senchafiddle.com/#XQNA8
Can any tell me why i keep getting a method buildItems not defined in the following code ? Am i escaping something essential ?
Ext.define('MyApp.view.Viewport', {
extend: 'Ext.container.Viewport',
requires: [
'Ext.layout.container.Border'
],
layout : 'border',
items : [this.buildItems()],
buildItems : function() {
return { region:'center',xtype:'panel'}
}
});
The buildItems method has no reason to be a public method, i was only trying this way first. This is the way i'm doing it now:
(function() {
function buildItems () {
return [
{
region : 'center',
xtype : 'panel',
}, {
region : 'west',
xtype : 'panel',
width : 225
},{
region : 'south',
xtype : 'panel',
height : 50
},{
region : 'north',
xtype : 'panel',
height : 50
}
]
}
return Ext.define('MyApp.view.Viewport', {
extend: 'Ext.container.Viewport',
requires: [
'Ext.layout.container.Border'
],
layout : 'border',
items : buildItems()
});
})();
Is this an overstretch ?
thx
The problem is: At the time of execution of the line
items : [this.buildItems()],
the scope is the Global Object, i.e. this evaluates to window.
You should not put items into a class anyway, since the instances may modify the item's items, so the right way to do it is
initComponent: function () {
this.items = this.buildItems(); // now, "this" is the current component instance
// superclass.initComponent...
}
Edit: As an answer to the second part of the question
This has been discussed a million times, and there's nothing wrong with making that helper function private. I personally tend to keep methods public, since that increases readability of the code. Usually I use doc comments (#private) as a marker, and quite simply avoid calling supposedly private methods. I think this is not a big deal, since I'm mostly not building libraries or anything reusable for third-party developers.
It is because the function is defined in another function and the viewport will be accessed outside this self-executing function. So, put this buildItems() outside the self-executing function and try the same.