Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

Compare the following examples:

Without IoC

{span:class=} | {code:javascript}
Wiki Markup
Span
classborderless-table
Code Block
javascript
javascript

/**
 * Component creator function
 */
fluid.myComponent = function (container, options) {
    var that = fluid.initView("fluid.myComponent", container, options);
    that.model = {
        ...
    };
    that.field = that.locate("inputField");

    // Instantiation of first subcomponent
    that.sub1 = fluid.initSubcomponent(that, "sub1",
        [that.options.selectors.sub1container, {
            model: that.model,
            field: that.field
        }]);

    // Instantiation of second subcomponent
    that.sub2 = fluid.initSubcomponent(that, "sub2",
        [that.model]);

    // Instantiation of third subcomponent
    that.sub3 = fluid.initSubcomponent(that, "sub3",
        [that.container, that.events.onSave]);

    return that;
};
{code} | This component creator function initializes three subcomponents. Each initialization requires a call to {{

This component creator function initializes three subcomponents. Each initialization requires a call to fluid.initSubcomponent()

}}

with

the

specific

parameters

that

the

subcomponent

implementation

requires

(the

array

of

parameters

is

the

third

argument

to

{{

fluid.initSubcomponent()

}}

).

The

second

argument

to

{{

fluid.initSubcomponent()

}}

is

the

string

name

of

the

subcomponent,

as

specified

in

the

defaults

(not

necessarily

the

actual

function

name).

| | {code:javascript}

Code Block
javascript
javascript

/**
 * Default options for the component
 */
fluid.defaults("fluid.myComponent", {
    sub1: {
        type: "fluid.mySubComponent1Impl"
    },
    sub2: {
        type: "fluid.mySubComponent2Impl"
    },
    sub3: {
        type: "fluid.mySubComponent3Impl"
    },
    selectors: {
        inputField: ".flc-myComponent-inputField",
        sub1container: ".flc-subComponent1"
    },
    events: {
        onSave: null,
        afterSave: null
    }
});
{code} | The {{[]}}{{

()

}}

call

declares

the

default

function

to

use

for

the

subcomponents,

by

name.

Users

can

override

these

defaults

by

specifying

a

different

function

name,

but

the

arguments

to

the

customized

replacement

must

be

the

same,

or

the

user

will

have

to

modify

the

code

that

calls

{{

fluid.initSubcomponent()

}}

for

that

subcomponent.

| {span}

With IoC

{span:class=} | {code:javascript}
Wiki Markup
Span
classborderless-table
Code Block
javascript
javascript

/**
 * Component creator function
 */
fluid.myComponent = function (container, options) {
    var that = initView("fluid.myComponent", container, options);
    that.model = {
        ...
    };
    that.field = that.locate("inputField");

    // initDependents() will instantiate all three subcomponents
    fluid.initDependents(that);

    return that;
};
{code} | With

With IoC,

the

component

creator

function

does

not

initialize

each

subcomponent

individually:

{{[]}}{{

()

}}

initializes

anything

that

is

defined

in

the

{{

components

}}

section

of

the

defaults

provided

to

{{

fluid.defaults()

}}. | | {code:javascript}

.

Code Block
javascript
javascript

/**
 * Default options for the component
 */
fluid.defaults("fluid.myComponent", {
    gradeNames: "fluid.viewComponent",
    components: {
        sub1: {
            type: "fluid.subComponent1Impl"
        },
        sub2: {
            type: "fluid.subComponent2Impl"
        },
        sub3: {
            type: "fluid.subComponent3Impl"
        }
    },
    selectors: {
        inputField: ".flc-myComponent-inputField"
    },
    events: {
        onSave: null,
        afterSave: null
    }
});
{code} | In the component

In the component defaults,

the

_

types

_

of

components

to

use

for

the

subcomponents

are

defined

inside

a

property

called

{{

components

}}

.

The

{{

fluid.initDependents()

}}

will

look

inside

this

property

for

the

list

of

dependents

to

initialize.

\\ \\ The values for the {{type}} properties may be function names, but this is not necessary. The function to use for the types specified, as well as their arguments, are specified through {{[fluid.demands]}}{{()}}, shown below. | | {tip:title=With IoC and "autoInit" grade} It is encouraged to use IoC system in conjunction with the component grade system. Using "autoInit" allows for simpler and more declarative implementation of component. The example of such "autoInit" component is below:{tip} | | {code:javascript}



The values for the type properties may be function names, but this is not necessary. The function to use for the types specified, as well as their arguments, are specified through fluid.demands(), shown below.

Tip
titleWith IoC and "autoInit" grade

It is encouraged to use IoC system in conjunction with the component grade system. Using "autoInit" allows for simpler and more declarative implementation of component. The example of such "autoInit" component is below:

Code Block
javascript
javascript

/**
 * Default options for the component with autoInit grade.
 */
fluid.defaults("fluid.myComponent", {
    gradeNames: ["fluid.viewComponent", "autoInit"],
    preInitFunction: "fluid.myComponent.preInitFunction",
    postInitFunction: "fluid.myComponent.postInitFunction",
    components: {
        sub1: {
            type: "fluid.subComponent1Impl"
        },
        sub2: {
            type: "fluid.subComponent2Impl"
        },
        sub3: {
            type: "fluid.subComponent3Impl"
        }
    },
    selectors: {
        inputField: ".flc-myComponent-inputField"
    },
    events: {
        onSave: null,
        afterSave: null
    }
});
fluid.myComponent.preInitFunction = function (that) {
    that.model = {
        ...
    };
};
fluid.myComponent.postInitFunction = function (that) {
    that.field = that.locate("inputField");
};
{code} | With autoInit

With autoInit grade,

the

component

creator

function

will

be

generated

from

component

defaults.

Any

code

present

in

the

old

style

creator

function

can

then

be

distributed

into

appropriate

lifecycle

functions

such

as

preInitFunction,

postInitFunction

and

finalInitFunction.

| | {code:javascript}

Code Block
javascript
javascript

/**
 * Subcomponent demands
 */
fluid.demands("fluid.subComponent1Impl", "myComponent", {
    container: "{myComponent}.options.selectors.sub1container",
    options: {
        model: "{myComponent}.model",
        field: "{myComponent}.field"
    }
});

fluid.demands("fluid.subComponent2Impl", "myComponent", {
    funcName: "fluid.mySubComponent2Impl",
    args: ["{myComponent}.model"]
});

fluid.demands("fluid.subComponent3Impl", "myComponent", {
    container: "{myComponent}.container",
    options: {
        events: {
            onSave: "{myComponent}.onSave"
        }
    }
});
{code} | The calls to {{

The calls to fluid.demands()

}}

specify

both

*

  • what
  • function
  • to
  • use
  • for
  • a
  • given
  • context,
  • and
*
  • what
  • arguments
  • to
  • provide
  • to
  • that
function \\ \\ The second call to {{
  • function

    The second call to fluid.demands()
}}
  • ,
  • for
  • example,
  • says:
*
  • use
  • the
  • function
{{
  • fluid.mySubComponent2Impl
}}
  • when
  • instantiating
{{
  • fluid.subComponent2Impl
}}
  • in
  • the
  • context
  • of
{{myComponent}} * pass the {{model}} property of the parent component as a parameter | | {code:javascript}
  • myComponent
  • pass the model property of the parent component as a parameter
Code Block
javascript
javascript

/**
 * Subcomponent demands
 */
fluid.demands("fluid.subComponent1Impl", ["testEnvironment", "myComponent"], {
    funcName: "fluid.mySubComponent1Impl",
    args: ["#test-markup", {
                model: testData.model,
                field: "{myComponent}.field",
            }]
});

fluid.demands("fluid.subComponent2Impl", ["testEnvironment", "myComponent"], {
    funcName: "fluid.mySubComponent2Impl",
    args: [testData.model]
});

fluid.demands("fluid.subComponent3Impl", ["testEnvironment", "myComponent"], {
    funcName: "fluid.myTest3Impl",
    args: [$("#test-markup"), testOnSaveHandler]
});
{code} | Additional calls to {{

Additional calls to fluid.demands()

}}

can

be

used

to

demand

different

arguments,

or

even

functions,

in

different

contexts.

This

example

shows

different

demands

when

the

subcomponents

are

being

used

by

{{

myComponent

}}

in

a

test

environment.

Test

data

can

be

provided

instead

of

actual

data,

if

desired.

The

third

subcomponent

is

demanding

a

completely

different

implementation.

\\ \\ These additional demands specification can be made in a different file, if desired. For example, demands specific to a testing environment can be placed in the test files. |{span}



These additional demands specification can be made in a different file, if desired. For example, demands specific to a testing environment can be placed in the test files.