Hello i am receiving an error from the code below, and not sure why because i thought i was defining it. I want to make sure my code is working properly before i add complexity to the report.
launch: function() {
this._createGrid();
},
_createGrid: function() {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Initiative'],
autoLoad: true,
enableHierarchy: true
}).then({
success: function(store) {
var myGrid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallytreegrid',
columnCfgs: ['Name', 'Owner'],
store: store
}],
renderTo: Ext.getBody()
});
}
});
this.add(myGrid);
},
});
"Error: success callback for Deferred transformed result of Deferred transformed result of Deferred threw: ReferenceError: myGrid is not defined"
I am new to this so any help would be greatly appreciated!
You issue you're running into is probably due to some confusion in how components and containers behave in ExtJS combined with the this scoping issue mentioned in the answer above.
Here's how I would write it:
_createGrid: function() {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Initiative'],
autoLoad: true,
enableHierarchy: true
}).then({
success: function(store) {
//The app class is already a container, so you can just
//directly add the grid to it
this.add({
xtype: 'rallytreegrid',
itemId: 'myGrid',
columnCfgs: ['Name', 'Owner'],
store: store
});
},
scope: this //make sure the success handler executes in correct scope
});
}
You also don't need to feel like you need to keep a myGrid reference around since you can always find it using the built-in component querying feature of ExtJS:
var myGrid = this.down('#myGrid');
You're defining myGrid inside of the success function scope, then trying to use it at the end of the _createGrid function, where it is undefined. I assume you're trying to do it that way because this is not bound correctly inside the success function. Try this instead:
_createGrid: function() {
var self = this;
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Initiative'],
autoLoad: true,
enableHierarchy: true
}).then({
success: function(store) {
var myGrid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallytreegrid',
columnCfgs: ['Name', 'Owner'],
store: store
}],
renderTo: Ext.getBody()
});
self.add(myGrid);
}
});
},
Related
I am trying to reference a store in my app for the purpose of adding a paging tool bar at the bottom of my gird. In most examples I have studied the store is referenced by variable, ex: store: someStore. However, by I have build my app a little differently and did create a reference variable to the store. I have
tried assigning an id but this did not work.
Here is what I have:
In my view Grid.js:
Ext.define('myApp.view.user.Grid', {
extend: 'Ext.grid.Panel',
viewModel: {
type: 'user-grid'
},
bind: {
store: '{users}',
},
columns: {...},
//my paging tool bar
dockedItems: [{
xtype: 'pagingtoolbar',
dock: 'bottom',
store: 'girdStore'
//store: {users} -> did not work
}],
...
});
In my view model GridModel.js:
Ext.define('myApp.view.user.GridModel', {
extend: 'Ext.app.ViewModel',
requires: [
'myApp.model.User'
],
stores: {
users: {
model: 'myApp.model.User',
storeId: 'gridStore',
autoLoad: true
}
},
formulas: {...}
});
When I try to reference the {users} store by id 'gridStore' I get this error:
Uncaught TypeError: Cannot read property 'on' of undefined
What is the best way to proceed without completely refactoring my model?
When you have a reference to your grid, you could get the store by calling the getStore function. See the ExtJs 6.2.1 documentation.
var grid; // reference to your grid
var store = grid.getStore();
You can create the store in initComponent and then attach it to the dockedItems, so both will share the same store.
initComponent: function () {
var store = Ext.create('Ext.data.Store', {
model: 'myApp.model.User',
storeId: 'gridStore',
autoLoad: true
});
this.store = store;
this.dockedItems = [{
xtype: 'pagingtoolbar',
dock: 'bottom',
store:store
}];
this.callParent(arguments);
}
The initComponent is called once when a new instance of the class is created, see the description in the documentation.
...It is intended to be implemented by each subclass of
Ext.Component to provide any needed constructor logic. The
initComponent method of the class being created is called first, with
each initComponent method up the hierarchy to Ext.Component being
called thereafter. This makes it easy to implement and, if needed,
override the constructor logic of the Component at any step in the
hierarchy. The initComponent method must contain a call to callParent
in order to ensure that the parent class' initComponent method is also
called...
The view with the initComponent function.
Ext.define('myApp.view.user.Grid', {
extend: 'Ext.grid.Panel',
viewModel: {
type: 'user-grid'
},
initComponent: function () {
var store = Ext.create('Ext.data.Store', {
model: 'myApp.model.User',
storeId: 'gridStore',
autoLoad: true
});
this.store = store;
this.dockedItems = [{
xtype: 'pagingtoolbar',
dock: 'bottom',
store: store
}];
this.callParent(arguments);
},
columns: {...},
...
});
I have a grid which uses a local store, that is created with an array. I tried to use this solution: Paging toolbar on custom component querying local data store
but it doesn't seem to work.
My code:
var myData = [];
//... fill myData
var store = Ext.create('Ext.data.ArrayStore', {
fields: fields,
data: myData,
pageSize: 10,
proxy: {
type: 'pagingmemory'
}
});
// create the Grid
var table = Ext.create('Ext.grid.Panel', {
id: "reportTable",
store: store,
columnLines: true,
columns: columns,
viewConfig: {
stripeRows: true
},
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
displayInfo: true
}]
});
Without this part of code the grid is showed but pagination doesn't work. With it the whole grid doesn't appear at all.
proxy: {
type: 'pagingmemory'
}
What could be the problem?
Most likely, the problem is that the PagingMemoryProxy.js is not being loaded.
Make sure you are loading this script explicitly (since this is part of 'examples', it is not part of the ext-all ) You can find this under <extjs folder>\examples\ux\data\PagingMemoryProxy.js
Ext.Loader.setConfig({
enabled: true
});
Ext.Loader.setPath('Ext.ux', 'examples/ux');
Ext.require('Ext.ux.data.PagingMemoryProxy');
In some ExtJS versions (ie. 4.2.2) the use of pagingmemory proxy is depracated.
Use the memory proxy with enablePaging configuration instead:
proxy: {
type: 'memory',
enablePaging: true,
}
Check the documentation of your ExtJS version to see if this configuration is enabled in your version.
I am trying to get value of this checkbox
Ext.define('myRoot.myExtApp.myForm', {
extend: 'Ext.form.Panel',
layout: {
type: 'vbox',
align: 'stretch'
},
scope: this,
constructor: function() {
this.callParent(arguments);
this.myFieldSet = Ext.create('Ext.form.FieldSet', {
scope: this,
columnWidth: 0.5,
collapsible: false,
defaultType: 'textfield',
layout: {
type: 'hbox', align: 'stretch'
}
});
this.mySecondForm = Ext.create('myRoot.myExtApp.myForm2', {
scope: this,
listener: this,
margin: '1 3 0 0'
});
this.myCheckBox = Ext.create('Ext.form.Checkbox', {
scope: this,
//id: 'myCheckBox',
boxLabel: 'Active',
name: 'Active',
checked: true,
horizontal: true
});
this.myFieldSet.add(this.mySecondForm);
this.myFieldSet.add(this.myCheckBox);
this.add(this.myFieldSet);
}
});
As you can see I have another form
Ext.define('myRoot.myExtApp.myForm2', {
where I have a handler, that should get the value of the checkbox from "myForm"
How can I get the value of my checkbox from Form2 without using Ext.getCmp? I know I can get the value of the checkbox if I do
Ext.getCmp('myCheckBox').getValue();
but using
this.myCheckBox.getValue();
gives me undefined error.
UPDATE - with Wared suggestion I tried this inside myForm2
this.temp=Ext.create('myRoot.myExtApp.myForm'), {});
var tempV = this.temp.myCheckBox.getValue();
I was able to get the value but I get the same true value even if I uncheck the box
I assume you worry about performance loss due to excessive use of component queries. A nice trick to minimize component queries could be to define a new method inside a closure in order to cache the result of the first getCmp call. Wrapping the definition of the method inside a closure allows to avoid using global scope or a useless class property.
getMyCmp: function (cmp) {
// "cmp" does not exist outside this function
return function () {
return cmp = cmp || Ext.getCmp('#myCmp');
};
}()
One solution could be :
myRoot.myExtApp.myForm.myCheckBox.getValue();
Beware, wrong answer. See comments below for a valid solution.
I am trying to create items inside a component as it gets initialized, with a function.
Consider the following:
Ext.define('mobi.form.Login',{
extend:'Ext.form.Panel',
config:{
items: [{
xtype: 'textfield',
name: 'Name',
label: 'Name'
}]
});
Ext.application({
viewport: {
layout:'fit'
},
launch: function(){
Ext.Viewport.add(Ext.create('mobi.form.Login'));
}
})
I am trying to get The mobi.form.login to generate its config from a function that runs on initialize ( or whatever I can use to over write the config I specify ).
I know Sencha touch 2 has the constructor, and initialize function, but both of them seem to have arguments=[] ( eg an empty array )
This is more or less how it would look if I was doing it in ExtJS 4.x:
Ext.define('mobi.form.Login',{
extend:'Ext.form.Panel',
initComponent:function(config){
config=Ext.apply({}.config,{});//make sure config exists
config.items= [{
xtype: 'textfield',
name: 'Name',
label: 'Name'
}]
Ext.apply(this, config);
this.callParent(arguments);
}
});
If you ever wanted to do this, you could use constructor or initialize.
Constructor you would use for synchronous logic which will be fast and you want to happen before the component is initialized. You can access the configuration through the constructors first argument:
Ext.define('MyComponent', {
extend: 'Ext.Component',
constructor: function(config) {
console.log(config);
this.callParent([config]);
}
});
Ext.application({
launch: function(){
Ext.create('MyComponent', { test: 1 })
// Will log out:
// {
// test: 1
// }
}
});
Remember you will always need to callParent with the config/arguments within constructor.
In any other situation, you should use initialize which is called after all the config's have been... initialized. :) We use this a lot internally for adding listeners.
initialize: function() {
this.on({
...
});
}
you don't need to call initialize manually it is already done by constructor and when calling this function you can access items data using this.items and create panel items there
Ext.define('mobi.form.Login',{
extend:'Ext.form.Panel',
config: {
items: []
},
initialize : function()
{
this.items = [Ext.create({
xtype: 'textfield',
name: 'Name',
label: 'Name'
})];
this.callParent();
}
});
Ext.application({
viewport: {
layout:'fit'
},
launch: function(){
Ext.Viewport.add(Ext.create('mobi.form.Login'));
}
})
Use the following:
Ext.apply(this, {
items: [
....
]
});
Have you tried something similar to this? I'm just passing a config object to Ext.create, though I can't test it right now. See http://docs.sencha.com/touch/1-1/#!/api/Ext-method-create
Ext.Viewport.add(Ext.create(
{
xtype: 'mobi.form.Login',
items: [ /*A list of items*/ ]
}
));
You could stick this snippet in its own function as well, one that takes in items as a parameter. Hope this solves your problem!
My callback code (js file) is something like
function addcontent(Title, tUrl, bURL, Id,purl){
alert(Id)
var runcontent = new Ext.Panel({
id: 'tt' + Id,
region: 'center',
autoLoad: {
url: tUrl,
callback: function(el){
addwindow(el, Id, bURL,purl);
},
scripts: true,
nocache: true
},
width: 600,
collapsible: false
});
}
function addwindow(el, Id, bURL,purl) {
//alert(el);
alert("add buttons " +{Id);
}
My problem is the call function is not going to addwindow. When I alert “Id” in addcontent it is displaying but not addwindow as the control is not moving to addwindow.
How can I trace/track what is the exception which is preventing the control to move onto addwindow.?
The proper approach to creating the callback with params is to use createCallback or createDelegate. Your functions are (apparently) executing in global scope so it wouldn't make much practical difference, but createDelegate allows your callback to execute within the same scope as the original function, which makes it the best default choice usually. So it would be something like:
autoLoad: {
url: tUrl,
callback: addwindow.createDelegate(this, [Id, bURL,purl]),
scripts: true,
nocache: true
},
Again, note that the this in your case will be the global Window object, but this is still a good practice to get into so that doing the same thing in the future within a class method will work as expected.
function addcontent(Title, tUrl, bURL, Id,purl){
alert(Id)
var runcontent = new Ext.Panel({
id: 'tt' + Id,
region: 'center',
autoLoad: {
url: tUrl,
callback: addwindow(Id, bURL,purl),
scripts: true,
nocache: true
},
width: 600,
collapsible: false
});
}
function addwindow(Id, bURL,purl) {
//alert(el);
alert("add buttons " +Id);
}