I want to send value from one view to another one, I have a code that's work in ExtJS 6 but not in ExtJS 4.
This is from the first one:
var test = Ext.create('test.text', {
delayedRenderTo: container_id,
id: 'messageBox-' + meta.rowIndex,
viewModel: {
data: {
value: value
}
}
});
and we bind it like this:
Ext.define('test.text', {
extend: 'Ext.Panel',
layout: {
type: 'vbox',
align: 'stretch',
overflow: 'scroller',
},
items: [{
xtype: 'textareafield',
grow: true,
growMin: 30,
growMax: 120,
disabled: true,
fullscreen: true,
bind: {
value: '{value}',
},
fieldStyle: 'font-weight:bold;'
}]
});
What is the alternative for ExtJS 4 ?
ViewModels were introduced in Ext JS 5 which is why it doesn't work in Ext JS 4.
To do it in Ext JS 4, you'd have to find the component (the textareafield in this case) and then execute the setter (setValue for this example). It's all manual in Ext JS 4.
Getting the component depends on many things but the best way is to use ComponentQuery and depends where the code executing this would be. First, you'd have to get your test.text instance and then use comp.child('textareafield'). I cannot give you a silver bullet example as it depends on many factors but using component's down, child, query, up methods a good start and they all have different purposes.
Related
I would like to know the pros and cons of define store VS create store in ExtJS. Which approach is better in case of many entities?
If you define a store, the store (if globally located and not inside a viewmodel) will be globally registered automatically on the app launch process if you require it..
Instead if you create a store runtime, you need to register it before using it like a global store (using regStore funcion)
In my opinion there aren't really differences in final functionality, in some cases you need to create a store runtime, in others you don't need it, and you can define it..
The real difference is the order on your code files.. is obviously better to define stores globally to check them if needed during code development..
In fact, if you need to update your code after a while, you could be disappointed to search a store inside your lines of code. Instead if you have a file that defines it you can search it more fast..
Obviously, defining a store, you also provide a class, that can be utilized again and again when you need.
So, in short words, define a store if you need it in more than one position in your code, if you need to use it twice or more, and if you need order on your code folders.
Instead, create runtime a store, when you need only like a temp one, during a function execution.
Quick tip: if you need a store only inside a single view, define it in the viewmodel of the view, is the better think on using a viewmodel architecture.
There really are not two cases, in which there is no better or worse.
The question is the means of applying to the problem that you need to solve.
100% of the cases recommend you set up your store, maybe the question you could ask is how you should instantiate your store.
90% of cases I instantiate the store globally defined in an application by the default template to be used.
The 10% case that I end up using in cases as a master / detail functionality, where I need to open multiple instances of the same functionality. If I do not instantiate the store for each instance of functionality, each change or load in the store will be replicated in the other open functionality, and this is a serious error for the user.
Set your store globally.
Here's an example of instantiating locally.
/**
* #class Litus.view.segundaviaBoleto.Grid
* Listagem de 2º via de boletos
*/
Ext.define('Litus.view.segundaviaBoleto.Grid',{
extend: 'Ext.grid.Panel',
xtype: '2viaBoleto-Grid',
require: [
'Litus.store.segundaviaBoleto.Store'
],
allowPaging: false,
multiSelect: false,
viewConfig: {
stripeRows: true,
enableTextSelection: true
},
/**
* #method initComponent
* Tratamento da inicialização do componente.
* #protected
*/
initComponent: function () {
var me = this;
//Locally instantiated the store at the start of the grid component, because this grid is opened several times.
me.store = Ext.create('Litus.store.segundaviaBoleto.Store');
Ext.applyIf(me, {
columns: [{
text: 'Documento',
width: 190,
sortable: false,
dataIndex: 'NumeroDocumento',
align: 'center',
style: 'text-align: center'
}, {
xtype: 'datecolumn',
text: 'Vencimento',
width: 130,
sortable: false,
dataIndex: 'DataVencimento',
format: 'd/m/Y',
align: 'center',
style: 'text-align: center'
}, {
xtype: 'numbercolumn',
text: '(R$) Valor',
width: 130,
align: 'right',
sortable: false,
dataIndex: 'ValorAtual',
style: 'text-align: center',
format: '#,##0.00'
}, {
text: 'Empresa',
flex: 1,
sortable: false,
dataIndex: 'Descricao',
align: 'left',
style: 'text-align: center'
}]
});
me.callParent(arguments);
}
});
I am using ExtJS 6 to build a filterable dataview panel, this is my panel : Panel.js
Ext.define('myApp.view.main.widgets.Panel', {
extend: 'Ext.panel.Panel',
....
viewModel: {
type: 'widgets-view-model',
stores: {
widgets: {
type: 'widgets'
}
}
},
items: [{
xtype: 'searchfield',
name: 'widgets-filter',
height: 24,
width: '100%',
bind: {
store: '{store}'
}
}, {
margin: '5 0 0 0',
autoScroll: true,
bodyPadding: 1,
flex: 1,
frame: true,
referenceHolder: true,
bind: {
widgets: '{widgets.data.items}'
},
setWidgets: function (widgets) {
this.lookupReference('the-widget-items-panel').setWidgets(widgets);
},
items: [{
layout: {
type: 'vbox',
pack: 'start',
align: 'stretch'
},
items: [{
reference: 'the-widget-items-panel',
xtype: 'the-widgets'
}]
}]
}]
});
The viewModel does nothing;
Ext.define('myApp.view.main.widgets.WidgetsViewModel', {
extend: 'Ext.app.ViewModel',
alias:'viewmodel.widgets-view-model'
});
In the view controller, I do the following in the view's afterrender event handler;
onAfterRender: function () {
var store = this.view.getViewModel().getStore('widgets');
store.load();
}
At which point, the widgets setter "setWidgets" is called as expected. However when I filter the store using the store's "filterBy" method, I expect the widgets setter "setWidgets" to be called, but it isn't.
I also tried resetting the store by doing the following;
store.removeAll();
store.load(function () {
console.log('reloaded...!')
});
to see if a reload of store data will trigger the widgets setter "setWidgets", but it doesn't.
It appears changes to the viewModel store only triggers calls to setters once only.
QUESTION:
Is this a feature of the framework or am I configuring things incorrectly.
How do I re-configure view/store/viewModel so that the widgets setter "setWidgets" is called for every update/change to the store, i.e. when;
data is loaded
store is filtered
store data changes
store updates
Filtering a store doesn't change the items instance, it only changes the contents - that's why setWidgets isn't being called again. If you want to respond to data changing in the store, you need to listen to events from the store.
Also - binding on widget.data.items is a bad idea; that's plugging into the internal structure of the store. Listen to the events instead:
load
filterchange
datachanged
update
Så i have noticed a very annoying bug in Sencha Touch. When i try to add the paging plugin to my dataview the "load more" text is placed above the items, not below like i want it to. It works with the standard listview.
I found another thread asking me to add "inifinte:true" to my dataview, but that did not help. Nor did "bottom:0" or "docked:'bottom'" options. Here is my code:
{
xtype: 'dataview',
plugins: {
type: 'listpaging',
loadMoreText: 'Indlæs flere..',
autoPaging: true
},
flex: 1,
cls: 'inspectionImages',
itemId: 'imageContainer',
padding: 10,
style: 'background: #F7F7F7; color: black',
emptyText: 'Der er ingen billeder på synet.',
itemTpl: ['...'],
loadingText: 'Henter billeder..',
store: 'Images'
}
Also here is an example sencha fiddle code - framework is 2.4.x:
Ext.application({
launch: function () {
var touchTeam = Ext.create('Ext.DataView', {
fullscreen: true,
plugins: {
type: 'listpaging',
loadMoreText: 'Indlæs flere..',
autoPaging: true
},
store: {
fields: ['name', 'age'],
data: [{
name: 'Jamie',
age: 100
}, {
name: 'Rob',
age: 21
}, {
name: 'Tommy',
age: 24
}, {
name: 'Jacky',
age: 24
}, {
name: 'Ed',
age: 26
}]
},
itemTpl: '<div>{name} is {age} years old</div>'
});
touchTeam.getStore().add({
name: 'Abe Elias',
age: 33
});
touchTeam.getStore().getAt(0).set('age', 42);
} // launch
}); // application()
I have checked with the Ext.dataview.dataview in the sencha touch documentation, and this shows similar behaviour when adding the paging plugin so i know that this is probably not my own fault. I really would like the loadinText to be placed in the bottom of the dataview. Any suggestions would highly be appreciated!
The List Paging Plugin is Developed for Lists.
If you are using it for the DataView then The Load more Text Will appear at the Top.
I have faced the same Problem.I have Gone Through the List paging Plugin Js.
Then Got Solution By just Changing the Css Property..
Inspect the "loading-spinner" CLass and change the Style to: style="font-size: 180%; margin: 10px auto;position:absolute; bottom: 0px; left: 50%
and Inspect the Class -"list-paging-msg" And change the style to style="position:absolute; bottom: 0px; left: 50%;"
This is a bug in Sencha Touch. Mitchell Simoens has told here that it is meant for List only but I believe this should also support the dataview as it is light compared to list.
In sencha forum solutions , you can see they have changed the xtype from dataview to list. I also had same problem and I did the same. But you can do some addition if you want the look and feel of dataview instead of list.
disableSelection: true,
pressedCls: '',
I hope this helps you. Let me know if you need anything else.
I have found the solution after gone through the code of List paging Plugin, Ext.dataview.DataView and Ext.dataview.List.
Initialize list paging plugin after dataview initialized, then the "load more component" position will be right.
Ext.define('MyDataView', {
extend: 'Ext.dataview.DataView',
config: {
/* do not set here
plugins: [{
xclass: 'Ext.plugin.ListPaging',
autoPaging: true
}, {
xclass: 'Ext.plugin.PullRefresh'
}]
*/
},
initialize: function() {
var me = this;
me.callParent();
// Initialize plugin here, so the listpaging component will append after dataview container
me.setPlugins([{
xclass: 'Ext.plugin.ListPaging',
autoPaging: true
}, {
xclass: 'Ext.plugin.PullRefresh'
}]);
}
}
As it turns out the pagingplugin were not meant for Dataview. It can be used though. In the end i ended up just manually moving the "load more" text in the DOM at the end of each load of the plugin. To ensure no listeners were lost i used the appendchild JS function and applying some custom css. Now everything works as expected.
I try to working with HTMLEditor in http://jsfiddle.net/WEEU3/
But when i chose Numbered list or Bullet list to typing then i press enter keyboard. That like
I think that like
1. first
2. second
3. third
And when i focus in third. I press to un-numbered. I think that like
1. first
2. second
third
But all word will be un-numbered
How to fix that. Thanks so much
It looks like there is a bug with htmleditor on 4.1.1. Also, you should NOT be using new to create the ExtJS objects. This will cause other ExtJS problems.
Upgrading to 4.2.x will fix your problem with the htmleditor.
Your code should be better formatted. You should also be using proper ExtJS methods to get items i.e. :
Ext.create('Ext.form.Panel', { // should be using Ext.create(), not new
title: 'HTML Editor',
width: 500,
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [{
xtype: 'htmleditor',
name: 'editor',
enableColors: true,
enableAlignments: false,
enableLists: true,
enableSourceEdit: false,
anchor: '100%'
}],
dockedItems: [{
xtype: 'toolbar',
items: [{
xtype: 'button',
text: 'Get HTML',
handler: function(btn) {
// example of getting all form values
console.log(btn.up('form').getForm().getValues());
// proper example of getting by component
alert(btn.up('form').down('htmleditor').getValue());
}
}]
}]
});
I want to break sencha architect 2 generated code into different classes
What i want is declare a tabpanel in another class and use instantiated class in the following code.
Ext.define('MyApp.view.MyWindow', {
extend: 'Ext.window.Window',
height: 430,
width: 748,
layout: {
type: 'fit'
},
title: 'Add New Business Unit',
modal: true,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'tabpanel',
frame: true,
activeTab: 0,
items: [
{
I think I understand what you are trying to do. So instead of typing up an answer(I feel lazy today...), I just created a short screencast which I hope explains what your are trying to achieve. http://screencast.com/t/RhiMAreJBTwb