Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

 

 

Div
classtutorial-linear-nav

Span
classtutorial-nav-left
Previous: Pick a component type
Span
classtutorial-nav-centre
Up to overview
Span
classtutorial-nav-right
Next: Tutorial - Model Components

Div
classfloatRight
Panel
borderColor#ccc
bgColor#fff
borderStylesolid
titleOn This PageborderStylesolid
Table of Contents
maxLevel5
minLevel2
Div
classfloatRight
Panel
borderColor#ccc
bgColor#fff
borderStylesolid
titleSee AlsoborderStylesolid

Component Grades
fluid.defaults
Options Merging
IoC - Inversion of Control
Component Lifecycle and autoInit

Regardless of which grade of component you use, the basic structure will be the same. We'll use the simplest grade, a little component, to illustrate what this structure is. In future pages explaining other grades, you'll see the same principles.

...

  1. declare the component grade and any default values for the component's options. Options are used by integrators to customize the behaviour of a component.
  2. define a creator function: a public function that is invoked to instantiate the componentany public functions that the component requires to do its work.

Grade and Default Options

A component's grade and any default options are registered with the framework using a call to fluid.defaults, which has two parameters: the component name and an object containing the defaults. The grade name is parent grades for the component are specified in an array in the defaults called gradeNames. For a little component, specify the grade as fluid.littleComponent:

Code Block
javascript
javascript
fluid.defaults("tutorials.simpleComponent", {
    gradeNames: ["fluid.littleComponent", "autoInit"],
    option1: "default value 1",
    ...
});

Options

The options you define for your component will be completely dependent on what your component does. Integrators can override your defaults when they instantiate the component, to customize its appearance or behaviour. The Framework will take care of merging the integrator's values with your defaults.

...

Code Block
javascript
javascript
fluid.defaults("fluid.progress", {
    ...
    showAnimation: {
        params: {
            opacity: "show"
        }, 
        duration: "slow"
    }, // equivalentforwarded ofto $().fadeIn("slow")
        
    hideAnimation: {
        params: {
            opacity: "hide"
        }, 
        duration: "slow"
    }, // equivalentforwarded ofto $().fadeOut("slow")
    ...
});

...

All components have a creator function: a public function that is invoked to instantiate the component. In general, the framework will instantiate the creator function for you automatically, given the component's default options. The framework will in general also take responsibility for calling the creator function for you automatically as well, when your component is registered as a subcomponent of another. In the rare case you need to construct a component directly using a JavaScript function call, Infusion components have a standardized function signature:

...

Creator functions can be defined in one of two ways

...

  1. using IoC - Inversion of Control: The framework will create the function according to your specifications

NOTE: The IoC system in Infusion is being introduced in version 1.4, and has Sneak Peek status. If you're working with production code, you might wish to use the "old-fashioned" method and write your own creator function, but otherwise, we do recommend that you use IoC.

Writing your own creator function

  1. directly: You write the function yourself - this option is not recommended and the ability to do this will be removed in Infusion 2.0

Using IoC

Automatic creator function generation

The IoC - Inversion of Control system can automatically generate a component creator function for you. This is accomplished by added a special grade to the gradeNames property: "autoInit":

Code Block
javascript
javascript
fluid.defaults("tutorials.simpleComponent", {
    gradeNames: ["fluid.littleComponent", "autoInit"],
    option1: "default value 1",
    ...
});

Note that in Infusion 2.0, "autoInit" will become the default for all components and will not need to be specified.

Public API methods

The standard means of adding public API functions to a component is to express them as Invokers. An invoker is a declarative record added into a components defaults, under the section invokers: the name of the record becomes the name of the public function which will be added. The invoker record defines the name of the public JavaScript function which should be executed when the method is called, as well as details of where the arguments that the function accepts should be sourced from - for example:

Code Block
javascript
javascript
fluid.defaults("tutorials.simpleComponent", {
    gradeNames: ["fluid.littleComponent", "autoInit"],
    option1: "default value 1",
    ...
    invokers: {
        publicFunction: {
            funcName: "tutorials.simpleComponent.publicFunction",
            args: "{that}"
        }
    }
});

// implementation of the public function registered as an invoker above
tutorials.simpleComponent.publicFunction = function (that) {
    ...
};

You will note that the function tutorials.simpleComponent.publicFunction is a standard JavaScript function that could even be invoked directly from code if this were found relevant - it need not be necessarily bound as a component method (although most component methods tend not to make sense without being provided an instance of the relevant component).

Example: Currency Converter via IoC

So what would our currency converter example look like, create using IoC:

Code Block
javascript
javascript
fluid.defaults("tutorials.currencyConverterAuto", {
    gradeNames: ["fluid.littleComponent", "autoInit"],
    exchangeRate: 1.035,
    invokers: {
        convert: {
            funcName: "tutorials.currencyConverterAuto.convert",
            args: ["{that}.options.exchangeRate", "{arguments}.0"] // amount
            }
        }
    }
});

// The conversion function
tutorials.currencyConverterAuto.convert = function (exchangeRate, amount) {
    return amount * that.options.exchangeRate;
};

You'll notice that in this case we have been able to avoid binding to the entire component instance in our public function, and so our standalone public function tutorials.currencyConverterAuto.convert is indeed of more general utility than just for building a component method. This has happened because its responsibilities are particularly well-defined - you should always take the opportunity to restrict the binding behaviour of your public functions in this way whenever it is appropriate. 

Writing your own creator function

Note that the scheme described here is not recommended for new code, and is described here only for completeness. The ability for users to write their component creator functions directly in JavaScript code will be removed in Infusion 2.0.

Creator functions follow a few basic steps:

...

Code Block
javascript
javascript
// The global namespace
var tutorial = tutorial || {};

(function ($, fluid) {

    // a creator function for a little component
    // creator functions are typically named by the component name itself
    tutorials.sampleComponent = function (options) {
        // call the framework component initialization function
        var that = fluid.initLittleComponent("tutorials.sampleComponent", options);

        // attach any public methods to the 'that' object
        that.publicFunction = function () {
            // ...
        };

        return that;
    };

})(jQuery, fluid_1_35);

Example: Currency Converter Creator Function

...

Code Block
javascript
javascript
// creator function for the currency converter component
tutorials.currencyConverter = function (options) {
    var that = fluid.initLittleComponent("tutorials.currencyConverter", options);

    // note that component methods have access to the values stored in 'options'
    // - the ones provided in the defaults and possibly overriden by implementors
    that.convert = function (amount) {
        return amount * that.options.exchangeRate;
    }
    return that;
};

Using IoC

Automatic creator function generation

...

Code Block
javascriptjavascript
fluid.defaults("tutorials.simpleComponent", {
    gradeNames: ["fluid.littleComponent", "autoInit"],
    option1: "default value 1",
    ...
});

With this special grade, you do not need to write a creator function at all.

Public API methods

But wait: What about public methods that we want to be part of the component's API? The Infusion Framework offers a number of hooks into the component creation lifecycle, and you can use one of these hooks to add your public methods. These hooks can be accessed by providing functions that will be executed at these moments in the lifecycle. These functions are speficied in the defaults for the component.

Adding public methods is typically done during the final initialization of a component. The hook for this – the default where you need to specify your function – is called finalInitFunction:

...

fluid.defaults("tutorials.simpleComponent", {
    gradeNames: ["fluid.littleComponent", "autoInit"],
    option1: "default value 1",
    ...
    finalInitFunction: "tutorials.simpleComponent.finalInit"
});

// the 'final init' function, which adds public methods to the component
tutorials.simpleComponent.finalInit = function (that) {
    that.publicFunction = function () {
        ...
    };
};

The things to note about this:

  • the finalInitFunction default takes the string name of the function
  • the function accepts the that object as an argument - your function simply adds methods to it

Example: Currency Converter via IoC

So what would our currency converter example look like, create using IoC:

Code Block
javascriptjavascript
fluid.defaults("tutorials.currencyConverterAuto", {
    gradeNames: ["fluid.littleComponent", "autoInit"],
    exchangeRate: 1.035,
    finalInitFunction: "tutorials.currencyConverterAuto.finalInit"
});

// The final init function
tutorials.currencyConverterAuto.finalInit = function (that) {
    that.convert = function (amount) {
        return amount * that.options.exchangeRate;
    }
};
Div
classtutorial-linear-nav

Span
classtutorial-nav-left
Previous: Pick a component type
Span
classtutorial-nav-centre
Up to overview
Span
classtutorial-nav-right
Next: Tutorial - Model Components