ExtJS cannot override methods statics - extjs

I wanted to extend Ext.Action class due to add my own methods, but I've encouraged problem Cannot override method statics on Core.app.Action instance.
I know that is a problem connected to overriding constructor. But don't know how to solve it other way.
Here is code of my component
Ext.define('Core.app.Action', {
extend: 'Ext.Action',
iconCls: 'icon-add',
currentData: undefined,
constructor: function(config){
config = Ext.applyIf(config || {}, this);
this.callParent([config])
},
handler: function (widget, event) {
Ext.Msg.alert("Name:", this.currentData.data.company)
},
getActionId: function () {
return this.actionId
},
setCurrentData: function (data) {
this.currentData = data
this.disable()
if (data.data.actions) {
this.currentData.data.actions.forEach(action => {
if (action === this.actionId) this.enable()
})
}
}
})
And there is a way how I create instance of mentioned class
Ext.create('Core.app.Action', {
actionId: 'D',
text: "Action D",
})
ExtJS is not throwing errors when I remove constructor from my class, but I can't also use methods such as handler or setCurrentData.
I've also tried overriding the component, but failed.
Answers in solution below weren't helpful in this case.
Reusable Action in Ext JS MVC

Related

Jest testing a class in window

I'm super lost how to do this.
We've got a class in window for Loqate called window.pca.Addresses
Then in our code we run this snippet of code in a react method:
const shippingControl = new pca.Address(shippingFields, { key: process.env.LOQATE_API_KEY });
window.setTimeout(() => {
shippingControl.load();
}, 3000);
My question is how do I write a jest test to mock the Address class in the window and then also add the load() method so we can test if it has been fired or not.
I've tried to spyOn the window object as both global and window as well as mocking it with jest.mock() which also hasn't worked.
I'm wondering if anyone else can guide me on how to do this?
Many thanks
You can add beforeEach to your test something like that:
beforeEach(() => {
Object.defineProperty(window, "pca", {
value: {
Addresses: { load: jest.fn(() => null) }
},
writable: true
});
});
You can test if it has been fired like this:
expect(window.pca.Addresses.load).toHaveBeenCalledTimes(1);

How call function in renderer html with Ext.js 4.2

Code is:
Ext.define("Myapp", {
extend: '',
config: {},
initComponent: function () {},
getGrid: function () {
Ext.create("Ext.grid.Panel", {
...
columns: [
{
header: 'xx',
renderer: function (value) {
return '<a onclick=''>text</a>';
}
}
]
});
},
test: function(){
alert(1);
},
});
In the above code, I want call test function in onclick event. I tried Myapp.test(), But it didn't work.
Is there any way to do this?
You have to add a listener to the cell and check inside the listener function if the user clicked the 'a' tag.
A good example has been made by Tyr
Take a look at this fiddle
ExtJS components working like simple object literals, so you can extend them with anything you want. In this case, i added the property "active" which can be checked in the beforeEdit listener.

What would keep setter methods from being created in sencha touch

I have a simple controller that I'm starting to build in sencha touch 2:
Ext.define('ScoreKeeper.controller.GameScores', {
extend: 'Ext.app.Controller',
config: {
refs: {
requestButton: 'button[name=RequestButton]',
responseArea: '#scoreResponse'
},
control: {
requestButton: {
tap: 'sendRequest'
}
}
},
sendRequest: function (){
Ext.Ajax.request({
url: 'message',
method: 'GET',
disableCaching: false,
scope: this,
callback: function(options, success, response) {
this.setResponse(response.responseText);
}
});
},
setResponse: function (responseText){
this.setResponseArea(responseText);
}
});
When I tap my requestButton the sendRequest method fires correctly but when it gets to the setResponse method, it fails on the this.setResponseArea step.
When I checked my browser dev tools, it looks like the getter methods for both of my refs get created, but neither of the setter methods do.
What would keep these methods from being created?
Assuming #responseArea refers to an HTML element like a <div>. To attribute the response from your server to the HTML element, do this:
this.getResponseArea.setHtml(responseText);
instead of
this.setResponseArea(responseText);.
Don't forget getResponseArea gets you the HTML element with #responseArea as id. When you got it, you can do whatever you want with it; for example:
this.getResponseArea.setValue(responseText);
or
this.getResponseArea.getValue();.
That's why there is a get but no set.

How to dynamically update a Marionette CollectionView when the underlying model changes

Seems like this should be obvious, but there seem to be so many different examples out there, most of which cause errors for me, making me think they are out of date. The basic situation is that I have a MessageModel linked to a MessageView which extends ItemView, MessageCollection linked to a MessageCollectionView (itemView: MessageView). I have a slightly unusual scenario in that the MessageCollection is populated asynchronously, so when the page first renders, it is empty and a "Loading" icon would be displayed. Maybe I have things structured incorrectly (see here for the history), but right now, I've encapsulated the code that makes the initial request to the server and receives the initial list of messages in the MessageCollection object such that it updates itself. However, I'm not clear, given this, how to trigger displaying the view. Obviously, the model shouldn't tell the view to render, but none of my attempts to instantiate a view and have it listen for modelChange events and call "render" have worked.
I have tried:
No loading element, just display the CollectionView with no elements on load, but then it doesn't refresh after the underlying Collection is refreshed.
Adding modelEvents { 'change': 'render' } to the view --> Uncaught TypeError: Object function () { return parent.apply(this, arguments); } has no method 'on'
I also tried this.bindTo(this.collection..) but "this" did not nave a bindTo method
Finally, I tried, in the view.initialize: _.bindAll(this); this.model.on('change': this.render); --> Uncaught TypeError: Object function () { [native code] } has no method 'on'
Here is the code
Entities.MessageCollection = Backbone.Collection.extend({
defaults: {
questionId: null
},
model: Entities.Message,
initialize: function (models, options) {
options || (options = {});
if (options.title) {
this.title = options.title;
}
if (options.id) {
this.questionId = options.id;
}
},
subscribe: function () {
var self = this; //needed for proper scope
QaApp.Lightstreamer.Do('subscribeUpdate', {
adapterName: 'QaAdapter',
parameterValue: this.questionId,
otherStuff: 'otherstuff',
onUpdate: function (data, options) {
console.log("calling sync");
var obj = JSON.parse(data.jsonString);
self.set(obj.Messages, options);
self.trigger('sync', self, obj.Messages, options);
}
});
},
});
Views.MessageCollectionView = Backbone.Marionette.CollectionView.extend({
itemView: Views.MessageView,
tagName: 'ul',
// modelEvents: {
// 'change': 'render'
// },
onAfterItemAdded: function (itemView) {
this.$el.append(itemView.el);
}
});
var Api = {
subscribe: function (id) {
var question = new QaApp.Entities.Question(null, { id: id });
question.subscribe();
var questionView = new QaApp.Views.QuestionView(question);
QaApp.page.show(questionView);
}
};
I am very grateful for all the help I've received already and thanks in advance for looking.
Try this:
var questionView = new QaApp.Views.QuestionView({
collection: question
});

Reusable Action in Ext JS MVC

I have a Grid Panel with a toolbar and an context menu.
The toolbar has a edit button and the context menu has a edit menu item.
Both shares the same properties (text, icon and handler)
Ext has something called Action which makes it possible to share functionality etc. between components, but til now I have had no success getting it to work in the MVC architecture
(I am using the new MVC architecture in 4.0)
My Action class looks like this:
Ext.define( 'App.action.EditAction', {
extend: 'Ext.Action',
text: 'Edit',
handler: function()
{
Ext.Msg.alert('Click', 'You did something.');
},
iconCls: 'icon-edit-user' ,
});
And in my context menu
requires: ['App.action.EditAction'],
initComponent: function()
{
var editUser = new App.action.EditAction();
this.items = [
editUser,
{
// More menuitems
}
...
];
this.callParent(arguments);
When running the code I get "config is undefined" in the console.
Can anyone point out what I am doing wrong?
Thanks in advance,
t
Passing an empty config to your constructor will avoid the error, but have unwanted consequences later because, unfortunately, the base class (Ext.Action) relies on this.initialConfig later on. For example, if you called editUser.getText() it would return undefined instead of the expected 'Edit'.
Another approach is to override your constructor to allow a no-arg invocation and apply your overridden configuration:
Ext.define( 'App.action.EditAction', {
extend: 'Ext.Action',
text: 'Edit',
constructor: function(config)
{
config = Ext.applyIf(config || {}, this);
this.callParent([config]);
},
handler: function()
{
Ext.Msg.alert('Click', 'You did something.');
},
iconCls: 'icon-edit-user' ,
});
As per Ext.Action constructor
constructor : function(config){
this.initialConfig = config;
this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
this.items = [];
}
You must supply config not to get config is undefined exception in the second line (precisely in config.itemId part).
Updating your code as var editUser = new App.action.EditAction({}); should help(passing new empty object as config).
Surely, you could add some properties to the config object too.

Resources