I'm creating a "wrapper" widget which is essentially a way of creating a custom widget rather than extending a certain widget.
I want to modify the params passed in the constructor
Example:
constructor : function(params) {
// do stuff
params['id'] += '-container';
}
The problem is that in the next step of the _Widget lifecycle, create or postMixInProperties, the id will be back to it's originally passed in value...
EDIT:
I'm trying to modify the given id for the parent widget which will be a "container" of multiple other widgets. I want to use the given id on one of those specific child widgets. By the time the widget lifcycle gets to postCreate the dijit has already been registered.
Alternatively if I can't modify the params from the constructor, what would be a good way to override the create method to modify the arguments and call the remaining functions in the lifecycle?
Related
Here is a widget class declared in a MyWidget.js module.
define(["dojo/Foo","myapp/Bar"], function(Foo, Bar) { return declare('MyWidget', [], {
postCreate:function() {
var bar = new Bar();
bar.sayHello();
}
})});
In this theoretical example, "myapp/Bar" is a class defined similarly by returning a declare call. Now let's assume that I have created "myapp/SpecialBar" by extending "myapp/Bar".
In another widget, I want to tell MyWidget to use "myapp/SpecialBar" instead of "myapp/Bar" like so:
require(["myapp/MyWidget","myapp/SpecialBar"], function(Foo, SpecialBar) {
//Now swap "myapp/Bar" module dependency of "myapp/MyWidget" to "myapp/SpecialBar"
var myWidget = new MyWidget();
});
I know ways to do this. For example, I could add a Bar attribute to "myapp/MyWidget" and assign the value of the Bar module. This would allow me to instantiate like this: new MyWidget({ Bar:SpecialBar }). However, this seems like too much ceremony. Is there a clean way to just swap an AMD dependency without any special treatment to the module definition?
That is the clean way. You cannot change the modules that a widget/module depends on, well, you could map them, but that's done globally, so then it always maps to a specific module.
If you could do that, you could break a lot of stuff as well, besides, such a feature does not exist in any language. Comparing require() with imports in Java and .NET, you will see a similar trend.
The only way to change the module, is by changing the behavior/state of the module, which means by overriding properties or functions. When a module is "swappable" it's often used as a property, examples where this occur:
The dojo/dnd/Moveable class allows you to set a custom dojo/dnd/Mover through the mover property. In this case the constructor is added as a property to the Moveable (reference guide)
All widgets with a dropdown inherit from dijit/_HasDropDown, which adds the dropdown widget itself as a property to the parent widget
The ScreenRender is initialised with ScreenRenderImpl in ScreenFacadeImpl.makeRender, while ScreenFacade is initialised in ExcecutionContextFactoryImpl. In some cases, I would like to add more functions in ScreenRender that can be invoked in Macro templates. Instead of overriding the ExecutionContextFactoryImpl and down to ScreenRenderImpl as well s MoquiContextListener, is there a way to simply inject a sub class of ScreenRenderImpl when ScreenFacade.makeRender?
A real case to get support of sri in macro template is:
I am trying to populate the options of select via list-options or entity-options or via manual option which return by sri.getFieldOptions(). But it is kind of bound to form fields. I want to use in non-form context. So I kind of want to extend ScreenRender to have a function like sri.getOptions().
I am working on ExtJS 4.2 now. There are 3 ways to access DOM elements - get, select, query.
I want to know the difference between them. Why three separate methods?
we have a question here: SVO
But it doesn't give me any clear answers. Looking for something specific / detailed answer.
Will be grateful if you can help with the explanation.
Thanks in advance :-)
EDIT based on answer below:
I am not much into jQuery so can't understand through comparison. Can anyone help me with the difference between an Ext.element and a composite element?
EDIT 2:
What is Ext.dom.Element? Any different from Ext.element? and if anyone could throw some light on "Ext.fx.Anim" package?
Ext.get
Ext.get is analogous to document.getElementById in that you can provide the ID of a DOM node and retrieve that element wrapped as Ext.dom.Element. You can also provide a DOM node or an existing Element.
// Main usage: DOM ID
var someEl = Ext.get('myDivId');
// Wrap a DOM node as an Element
var someDom = document.getElementById('myDivId');
someEl = Ext.get(someDom);
// Identity function, essentially
var sameEl = Ext.get(someEl);
Ext.query
Ext.query allows you to select an array of DOM nodes using CSS/XPath selectors. This is handy when working with custom components or data views and you need a more robust selection mechanism than DOM IDs.
// Get all DOM nodes with class "oddRow" that are children of
// my component's top-level element.
var someNodes = Ext.query('.oddRow', myCustomComponent.getEl().dom);
Ext.select
Ext.select is essentially Ext JS's answer to jQuery's selectors. Given some CSS/XPath selector, it returns a single object representing a collection of Elements. This CompositeElement has methods for filtering, iterating, slicing the collection.
Most importantly, the CompositeElement supports chainable versions of all methods of Ext.dom.Element and Ext.fx.Anim that operate on each element in the collection, making this method very powerful.
Edit 1: An Ext.Element represents a single DOM node, while an Ext.dom.CompositeElement represents a collection of DOM nodes that can be affected through a single interface. So, given the following example:
// Set the height of each table row using Ext.query
var tableRowNodes = Ext.query('tr', document.getElementById('myTable'));
Ext.Array.each(tableRowNodes, function (node) {
Ext.fly(node).setHeight(25);
});
// Set the height of each table row using Ext.select
var compositeEl = Ext.select('#myTable tr');
compositeEl.setHeight(25);
You can see how much easier it is to work with Ext.dom.CompositeElement.
Edit 2: Ext JS supports the concept of alternate class names. Think of them as shortcuts for commonly used classes. Ext.Element is the alternate class name for Ext.dom.Element and can be used interchangeably.
Ext.fx.Anim is a class representing an animation. Usually not used directly, it is created behind the scenes when performing animations on elements or components. For example, the first parameter of Ext.Component#hide is the animation target.
I have a ListView bound to an ObjectDataSource, I'm passing some custom parameters to the Insert and Update methods on my bound class methods by adding them to the event.Values map in the ListView ItemInserting/ItemUpdating events.
However when I try to do the same thing on the ItemDeletingEvent the additional parameters do not seem to be passed to the datasource ( If I register a listener for ObjectDataSource.ItemSourceDeleting I only see one parameter, effectively the 'id' of the row).
Is this an expected behavior? I can't see anything in the documentation that indicates as such.
I found a solution -
I Added a 'DeleteParameter' value with the same name as my desired 'custom' parameter to the ObjectDataSource declaration.
Then in the ItemDeleting Event get the ObjectDataSource.DeleteParameters["myparam"] and set the DefaultValue property. Seems like a hack, but it does work.
From the dojo documents on dijit.registry, I see the forEach method accepts a last parameter thisObject. But it doesn't way what that object is. Is it a dijit widget or a dojo object?
I want to destroy all widgets inside an element (that will be replaced by AJAX) so they can be parsed again without conflicting id's.
dijit.registry.forEach(function(w) {
w.destroyRecursive();
}, dojo.byId("ajaxElement"));
But this destroys ALL widgets on the page...
The thisObject is the scope object to invoke the function passed in as the first parameter of forEach.
A couple of solutions you can use in this case:
1) Use dijit.findWidgets to find all the dijits in a DOM node and destroy them one by one.
dijit.findWidgets returns array of widgets which takes domnode as a parameter
2) dojo.parser.parse returns an array of all the dijits that it creates, store that array and destroy the dijits before you call dijit.parser.parse again.
3) Use dijit.registry.filter to filter out the dijits you want to keep.