I am trying to convert a class that extends Ext.app.Controller to extending Ext.app.Application. Since Ext.app.Application is a child class of Ext.app.Controller I assumed that simply changing the class being extended would work, instead however, it causes an error in the console that says Uncaught TypeError: Cannot call method 'substring' of undefined. The error occurs at the this.callParent(arguments) inside the constructor: function, Does anyone have any suggestions as to what might be causing this?
You cannot use a constructor within a Ext.app.Application class changes will come with 4.2 but till that use the launch method for example to apply stuff. And do NOT extend.
Application is sort of a singleton instance an get just intialized by calling
Ext.application({
name: 'MyApp',
launch: function() {
Ext.create('Ext.container.Viewport', {
items: {
html: 'My App'
}
});
}
});
Trying to run more instances result in problems but you will be able to do this with 4.2 like so
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
name: 'MyApp'
...
});
Ext.application('MyApp.Application');
Related
With CanJS (3), I'm trying to insert twice the same component, but with a different behavior.
The 'parent' stache looks like :
<div class="container-fluid contents">
<...>
<my-component someParameters="value1"></my-component>
</...>
<...>
<my-component someParameters="value2"></my-component>
</...>
</div>
Thanks to to-child binding, the parameter is getting in the child viewModel, which is a simple DefineMap.
The child component is simple :
export default Component.extend({
tag: 'my-component',
viewModel: myviewmodel (a DefinedMap, with a can-connect attribute, and some others attributes),
view: view (some stache file),
events: {
'inserted': function(el) {
console.log('inserted my-component...');
},
}
});
So far so good, I achieve to have both on the same window, and while displaying the custom parameters, it shows the difference.
But then came troubles.
Both child component has a connection, (in the viewmodel), and I expect then to connect to the same IP, but to subscribe to a different channel.
It looks like CanJS doesn't instanciate two distincts viewmodel in facts, so I end up with the same instance of my can-connect object, which make the work impossible ...
If anyone has an idea of how to have two components on the same pagem but with two different scope, I'll be pleased to read it.
EDIT:
The real problem is the non-unicity of the "model" (ie the viewmodel.connect object)
The solution :
The can-connect object must be in a closure :
var behaviors = function() {return connect([
someBehavior,
anotherBehavior
],
{
url: {
getListData: "GET myURL"
}
})
};
And the DefineMap must be like :
var MyMap = DefineMap.extend({
connection: {value: behaviors},
parameters: ...
}
Some interesting reading :
value attribute doc
I was reading the Declarative Listeners documentation (from this thread's answer), and I'm very confused about something. The documentation states:
On the other hand, instance-level listeners skip the component and
resolve to a ViewController upward in the hierarchy starting with the
parent Container.
With the example of:
Ext.define('MyApp.view.main.Main', {
extend: 'Ext.container.Container',
controller: 'main',
items: [
{
xtype: 'user',
listeners: {
remove: 'onUserRemove'
}
}
]
});
Ext.define('MyApp.view.main.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
onUserRemove: function() {
console.log('user removed');
}
});
Which tells me that the user class has its own controller, but the listeners attached to it (in the Main View class) will be resolved to the Main View's Controller. Great, that makes sense. However, what doesn't make sense is if you add items to this class, and one of these items has a listener on it... this listener apparently tries to resolve to the class's controller.
Here's an example. I have a SearchPanel class that has a ViewModel and a ViewController. The ViewController controls things like pressing the Search button and any other logic I'd desire for this class. Now, because my SearchPanel is a sort of "base" class that I'll be using across my app, I can't define its items, as they'll vary from view to view. So when I go to define my items in the instance-level config, I'm going to have listeners for some of these items. Unfortunately, it looks like these listeners try to resolve to the SearchPanel class, which is not what I want... I want them to resolve to the ViewController for the defined class.
In my example, I would like Textfield's listener to resolve to MyView's controller. You'll notice if you type in the textfield, there will be an error in the console. Is this a bug, or is this by design? If it's by design, how can I get this to work?
I have a simple Extjs4.2 MVC application. I have created a view and linked that view to apps controller using refs. In refs I have tried using alias/itemId of that view. Here is the refs:
refs: [{
ref: 'answersCont',
selector: 'question' //-- alias of view
}],
But I am not getting view constructor when using this.getAnswersCont().
Can anyone please help me identifying what is the missing link here?
It seems question view is not rendered in the DOM. So you need to use autoCreate:true in your ref which will first run the ComponentQuery to see if a Component matching that selector exists on the page. If not, it will automatically create one using the xtype provided.
Like this:
refs: [{
ref: 'answersCont',
autoCreate:true,
selector: 'question' //-- alias of view
}],
I have a very simple extension in Ext JS from Ext.form.Panel:
Ext.define('path.to.SomeClass', {
extend : 'Ext.form.panel',
xtype : 'some-class'
config : {
hasDog : true
},
constructor : function (config) {
if (this.config.hasDog) {
// do something dog related
} else {
// do something not dog related
}
}
});
I then have a "container" for this custom componet:
Ext.define('path.to.OtherClass', {
extend : 'Ext.window.Window',
// ....
items : [{
xtype : 'some-class',
hasDog : false
}]
});
However, for some reason unknown to me, the if...else evaluation in SomeClass is always picking up the default configuration for hasDog. Am I not correctly configuring some-class in OtherClass's items config?
To add a bit more context, OtherClass is called via some using code:
var window = Ext.create('path.to.OtherClass');
window.show();
From what I can see, the above is pretty standard stuff - at least in thought.
The reason why you always get the default configuration is because you're accessing this.config, which is the declaration of your configuration, instead of the actual configuration from the constructor argument. So either use config or - once you've called the parent class constructor - this.
constructor : function (config) {
// before parent class constructor or this.initConfig was called:
console.log(config.hasDog);
// call parent class constructor
this.callParent(arguments);
// after parent class constructor or this.initConfig was called:
console.log(this.hasDog);
}
Also have a look at the documentation:
Note: You need to make sure Ext.Base.initConfig is called from your constructor if you are defining your own class or singleton, unless you are extending a Component. Otherwise the generated getter and setter methods will not be initialized.
In your case, since your extending a component, calling the parent constructor should suffice (as shown in the example above).
I want to create a custom component(container) that would contain other components (labels, buttons,...).
I would like to create some kind of a class so I would be able to create multiple instances of this component but with different params. Somekind of constructor. These params would set the labels and button options.
I am using Sencha Architect, so I am wondering is this possible and how it could be done?
Via ExtJS code you just can use the Ext Class System:
Ext.define('MyOwnView', {
extend: 'Ext.container.Container',
constructor: function () {
// ... your code
}
});
To achieve this via Architect GUI, follow this guide (with screenshots):
http://docs.sencha.com/architect/3/creating_an_application/working_with_classes.html
You can use Ext.define (http://docs.sencha.com/extjs/4.2.2/#!/api/Ext-method-define) to define your new class prototype as follows:
Ext.define('My.app.Panel', {
extend: 'Ext.panel.Panel',
requires: [
'My.app.PanelPart2',
'My.app.PanelPart3'
]
constructor: function (config) {
this.callParent(arguments); // calls Ext.panel.Panel's constructor
//...
}
});