We do use callback mechanisms and events in various ways in different development platforms. But in .NET, it introduces delegates and events in an elegant and abstract manner. As inspired by delegates, Humax enables to you declare delegates and events as like in .NET.
See the following example:
Humax.declareNamespace("HxTest");
HxTest.Inventory = function(available)
{
this._reorderLevel = 5;
this._capacity = 10;
this._available = available;
}
HxTest.Inventory.prototype =
{
_reorderLevel : 0,
_capacity : 0,
_available : 0,
StockAlert : new Humax.Delegate("StockAlert", Function("message, ordered, available","")),
placeOrder : function(quantity)
{
if(this._available - quantity > this._reorderLevel)
{
this._available -= quantity;
}else
{
this.StockAlert.invoke("Reorder level alert", quantity,
this._available);
}
},
fillInventory : function(quantity)
{
if(this._available + quantity <= this._capacity)
{
this._available += quantity;
}else
{
this.StockAlert.invoke("Stock full", quantity,
this._available);
}
},
getAvailableStockCount : function() {return this._available;}
}
The above code defines an “Inventory” class with very simple attributes and methods. There is no order item detail specified in the example for simplifying to explain “Delegates”. The class defines a delegate named “StockAlert”:
StockAlert : new Humax.Delegate("StockAlert", Function("message, ordered, available",""));
This declaration defines a delegate named “StockAlert”, which will encapsulate any method that takes three parameters “message”, “ordered” and “available”.
Discipline #5: Humax strongly recommended to use JavaScript’s “Function” should be the second parameter of Deletage declaration. The first argument of the “Function” should be argument list separated by comma (“,”). The second argument of the “Function” must be empty string.
Once the delegate is defined, you can encapsulate a member method with that delegate by instantiating the delegate.
In the above class declaration, the “StockAlert” delegate is invoked whenever the stock will reach either minimum reorder level or exceeds the actual capacity of the inventory. These are declared in “placeOrder()” and “fillInventory()” methods respectively. The delegate can be invoked by its “invoke()” method with the parameters listed on its declaration”.
Note: Due to the typeless nature of JavaScript, Humax delegates can only verify the number of arguments and not check the types.
The following code explains how to the delegate is invoked:
var inventoryInst = new HxTest.Inventory(7);
inventoryInst.StockAlert.setTarget(stockAlertHandler);
function stockAlertHandler(message, ordered, available)
{
alert(message + " Ordered:" + ordered + " Available: " + available);
}
The above creates new instance of HxTest.Inventory with available stock is 7. The setTarget() method of the delegate “StockAlert” can be used to specify a method as a instance of this delegate. In this, stockAlertHandler() as the instance.
Now in your HTML page, create two textboxes and two buttons named “stockText”, “orderText”, “fillButton” and “orderButton”. Define the “value” and “onclick” handler of the buttons fillButton and orderButton are “Fill Inventory”, “Place Order”, “fillButton_onClick()” and “orderButton_onClick() respectively. See the following code:
<input type="text" id="stockText" /> <input type="button" id="fillButton" value="Fill Inventory" onclick="fillButton_onClick()" /> <input type="text" id="orderText" /> <input type="button" id="orderButton" value="Place Order" onclick="orderButton_onClick()" />
In your script, define the following:
function fillButton_onClick()
{
var quantity = parseInt(document.getElementById("stockText").value);
inventoryInst.fillInventory(quantity); }
function orderButton_onClick()
{
var quantity = parseInt(document.getElementById("orderText").value);
inventoryInst.placeOrder(quantity);
}
Run the page and enter value “4” in the first text box and press “Fill Order” button. An alert message “Stock full Ordered: 4 Available: 7” will be displayed. Enter “9” in the second text box and press “Place Order” button. An alert message “Reorder level alert Ordered: 9 Available: 7” will be displayed.
You can call two implementing methods through a single delegate. This becomes particularly important when handling Humax events. For example, in the above code, “StockAlert” can only encapsulate one implementing method. With Humax multicast delegate, you can encapsulate more than one implementing method.
Note: Unlike C#, Humax multicast delegate does not support for non-void return type.
There is no difference in the multicast delegate from delegate:
StockAlert : new Humax.MulticastDelegate("StockAlert", Function("message, ordered, available",""));
Instead of using “setTarget”, you should call “addTarget” to add an implementing method. For example, create a “div” tag in the same page as like
<div id="resultPanel"/>
Then modify the target assignment code as
inventoryInst.StockAlert.addTarget(stockAlertHandler); inventoryInst.StockAlert.addTarget(stockAlertHandler2);
Add the implementing method as
function stockAlertHandler2(message, ordered, available)
{
document.getElementById("resultPanel").innerText =
message + " Ordered:" + ordered + " Available: " + available;
}
Run the page with the above mentioned values. The delegate first popup the alert message, then displays the same message in the div tag.
You can use “removeTarget()” to remove a particular method from “StockAlert” or “removeAllTargets()” to remove all methods.
As per the observer design pattern, any objects can publish one or more events to which other classes can subscribe. Whenever the publishing class rises an event, all the subscribed classes or functions are notified.
Like C#, events are implemented with multicast delegates. The publishing class defines a multicast delegate that the subscribing class or function must implement. In C#, the method is called as “event handler”. We also use the same name in Humax.
Declare “OnStockAlert” event in “Inventory” class followed by the “StockAlert” delegate:
OnStockAlert : null
In the class constructor declare “OnStockAlert” as
this.OnStockAlert = new Humax.Event(this.StockAlert);
The argument specifies the underlying delegate for the event. In this case, it is “StockAlert”.
To attach an event handler to the event:
inventoryInst.OnStockAlert(Humax.EventAction.AttachHandler, stockAlertHandler); inventoryInst.OnStockAlert(Humax.EventAction.AttachHandler, stockAlertHandler2);
The first argument of the OnStockAlert (and any event) must be “EventAction”. It provides options to attach, detach event handlers or invoke (trigger) event.
Update the fillInventory() and “placeOrder()” methods of Inventory class like:
placeOrder : function(quantity)
{
if(this._available - quantity > this._reorderLevel)
{
this._available -= quantity;
}else
{
this.OnStockAlert(Humax.EventAction.Trigger, "Reorder level alert", quantity,
this._available);
}
},
fillInventory : function(quantity)
{
if(this._available + quantity <= this._capacity)
{
this._available += quantity;
}else
{
this.OnStockAlert(Humax.EventAction.Trigger, "Stock full", quantity,
this._available);
}
}
Now execute the program.