Component Inheritance

The page contains information about inheritance from components of Foresight Analytics Platform and enhancement of their capabilities.

Namespaces

All classes, global functions and enumerations must be defined in the PP namespace or its subnamespace in a certain way. For example:

PP.initNamespace(PP.Ui = {}, "PP.Ui"); 

The second parameter determines name of the resource that must be loaded together with namespace.

Classes

PP.Class1 = function (settings){};
PP.initClass(PP.Class1, baseClasses, "PP.Class1", baseIntf);

baseClasses - a link to a base class or an array, the first element of which is a base class and others are mixin objects.

baseIntf  - array of interfaces that are implemented by this class.

Each class must be inherited from the PP.Object base class.

Class constructor accepts for input the first parameter - settings. This is an object with property values for the created object. Example:

PP.Class1 = function (settings){
      this._ImageUrl = "";
      this._Caption = "text";
      PP.Class1.base.constructor.apply(this, arguments); //Call base class constructor
};
var c = new PP.Class1({ImageUrl : "url", Caption : "someText"});

After the constructor worked, an object with filled fields from "settings" is obtained.

Note that before calling the basic class constructor, those fields are described, to which it is possible to assign values via "settings", service fields are described after calling the basic class constructor.

Properties

Class property is described in the following way:

Description of property field in the class constructor, for example, ImageUrl, as it is described in the example above.

Field name must be added with the "_" prefix and must start with a capital letter. If a class field has the type ( Boolean | Number | String ), its initial value should be determined as ( false | 0 | "" ) respectively. Getter and setter are described via the definition in the function class prototype:

PP.Class1.prototype.setImageUrl = function (value){
      this._ImageUrl = value;
};
PP.Class1.prototype.getImageUrl = function ()
{
      return this._ImageUrl;
};

If the property is read-only, setter function must not be determined; if the property is write-only, getter function must not be determined.

If these functions do not contain any logic, it is recommended to determine getter and setter via a secondary function to reduce code length:

PP.Object.defineProps(PP.Class1, ["ImageUrl"], true);

The last parameter determines whether to generate setter for this property.

If the property has parameters, getter and setter must be described as follows:

PP.Class1.prototype.set<PropertyName> = function (value, param1, param2, param3)
{
      this._Property = value;
};
PP.Class1.prototype.get<PropertyName> = function (param1, param2, param3)
{
      return this._Property;
};

That is, the first setter's parameter is always a value assigned to the property.

Methods

Class methods must be determined via a prototype function:

PP.Class1.prototype.start = function ()
{

...

};

Public methods are named as follows. Protected/private methods are also determined in the class prototype and are named with the "_" prefix.

Events

Events are implemented via the PP.Delegate class. Each component event must be clearly determined, for example:

PP.Component = function(settings)
{   
      this._defineEvents(["Click", "MouseOut"]);  //All events are determined before calling base class constructor
      PP.Component.base.constructor.apply(this, arguments);
}
var c = new PP.Component();
c.Click.add(<handler or other delegate>, <Handler context, this is c object by default>);
c.Click.remove(<handler or event handler identifier>, <handler call context>);

Each event handler is called in a context with two parameters:

Event handlers must be named using the "on" prefix, events must be named without the "on" prefix. Events must be named according to the standard https://msdn.microsoft.com/en-us/library/ms229012.aspx by the UpperCamelCase rule. Use verbs or verb-based phrases in event names. Mark past and future in event names by means of the past and the future tenses. For example, the close event that is generated before closing the dialog box is named Closing, the event that is generated after closing the dialog box is named Closed. Do not use the Before and After prefixes and suffixes to indicate previous or following events. Use two parameters named sender and args in event handler signatures. The sender parameter must store a link to event generator object, and the "args" parameter must be a JSON object with event parameters.

To add a handler, on creating an object specify the field in the "settings" object:

new PP.Component({
      Click: function () { alert(1) },
      MouseOut: PP.Delegate(function () { alert(2) }, window)
})

Static Class Members

Static class members are determined as a field in the class constructor object:

PP.Class1.func = function()
{
};

It is prohibited to describe classes, interfaces and enumerations inside other classes.

Constants

Class constants must be written in the upper case, for example:

PP.Class1.CONST = "Value";

Enumerations

Enumerations must be described by means of the following structure:

(PP.ColorType = function ()
{
       var t = PP.ColorType;
       t.HSV = "HSV";
       t.RGB = "RGB";
       t.ARGB = "ARGB";
       t.PPBI = "PPBI";
       PP.initEnum(t, "PP.ColorType");
})();

Interfaces

Interfaces must be described as follows:

(PP.IDisposable = function ()
{
      PP.initInterface(PP.IDisposable, "PP.IDisposable", <base>);
      PP.IDisposable.Data = PP.ClassMembers.Property;
      PP.IDisposable.PropertyChanged = PP.ClassMembers.Event;
      PP.IDisposable.dispose = PP.ClassMembers.Method;
})();

Interface names must start from I.

<base> - a link to a basic interface or array of interfaces.

Mixins

Mixins are described via a standard JS object with a set of functions:

PP.Ui.Mixin = {
      func : function() {}
};

Only functions can be determined in a mixin.

Comments

Write comments only using //.

Exceptions

Errors must be generated via the operator:

throw PP.Exception("message", <context>)

Using the following set of errors:

PP.Exception, PP.ArgumentException, PP.ArgumentNullException, PP.OutOfRangeException.

It is prohibited to use the "try catch" operator to pass control to the other code part or for error dummy.

Next article: Coding Principles