|
#1
|
|||
|
|||
|
Let's say your application has an "Order" window that shows an order. How do you create multiple "Order" windows? Since all the layout items in the window have an ID that is, apparently, in the global namespace?
|
|
#2
|
|||
|
|||
|
Component IDs are optional, if you don't specify one, SmartClient will generate a unique ID. So that's one option. The other option is to template the ID based on the ID of the creating component. For example:
Code:
isc.defineClass("OrderWindow", "Window").addProperties({
title: "Order",
initWidget: function () {
this.Super("initWidget", arguments);
this.addItem(isc.DynamicForm.create({
ID: this.getID()+"_form",
fields: [...]
}));
}
});
isc.OrderWindow.create({
ID: "productOrder",
...
});
isc.OrderWindow.create({
ID: "itemOrder",
...
});
Of course if you're not interested in having global handles to those forms, you can just leave the ID out of their creation block. Does this answer your question? |
|
#3
|
|||
|
|||
|
Actually, a more generally useful pattern is to create two-way pointers between the creating and created components. Check out these two examples for a sample:
http://www.smartclient.com/#_Extending_Component.Reuse http://www.smartclient.com/#_Extending_Pattern.Reuse In both of these, the creating component passes a pointer to itself to the created component. This completely avoids the use of globals and is a cleaner approach. |
|
#4
|
|||
|
|||
|
Yes, this is more like the pattern I was looking for. Exactly what I was doing in my own code until I discovered SmartClient. What I'm not getting to work is passing data through to the constructor. For example, in the caller
Code:
var record = this.getSelectedRecord(); isc.CustomerSummary.create(record); Code:
isc.defineClass("CustomerSummary", "Window");
isc.CustomerSummary.addProperties({
initWidget : function () {
this.Super("initWidget", arguments);
isc.say(arguments.length);
}
})
|
|
#5
|
|||
|
|||
|
The properties on 'record' that you're passing through to create() actually get applied to the class instance directly. So, for example if you have:
Code:
var record = {foo: "bar", zoo: 5};
isc.CustomerSummary.create(record);
At present, arguments passed to create() don't make it all the way to initWidget(), but this seems like a useful pattern, so it will be next release if SmartClient. |
|
#6
|
|||
|
|||
|
So then here is what I've come up with as a pattern. It's common in my app to have a button or other control spawn a Window (a custom class as shown in the above examples' links) that need both data from, and a link to, it's parent. The launch button:
Code:
this.lookupProductButton = isc.IButton.create({
title:"Lookup Product",
parent: this,
spawnProductLookupWindow: function() {
var data = {
parent: this.parent,
DATA: this.parent.DATA
};
isc.ProductLookupWindow.create(data);
},
click:"this.spawnProductLookupWindow()"
});
Code:
this.setTitle(this.DATA['CUSTOMER_NAME']); Code:
this.parent.parent.orderLinesGrid.addData(record); A assume this, or some approximation thereof, is a typical pattern for doing this? |
|
#7
|
|||
|
|||
|
That's accurate. To the extent that it becomes cumbersome, you can avoid the parent.parent.parent type of chaining by passing in a named reference to the top-level component or use a global reference.
|