EController

Members

(readonly) name :CtrlName

Full name of the controller, i.e. the name from which the controller was instantiated.

Type:
Source:

(readonly) node :ControlledElement

The DOM element/node this controller is bound to.

Every controller is bound to a DOM element in the document, either through binding or direct attachment. And at the core of every component is direct communication with the element it is bound to.

Type:
Source:

Methods

bind(processopt)

Signals the framework that the element's inner content has been modified to contain new child controlled elements, and that it is time to bind those with the corresponding controllers.

It will search for all child elements that contain attribute data-e-bind / e-bind, but without controllers yet, create and initialize controllers, as specified by the attribute, which is expected to contain valid names (comma-separated) of existing controllers.

This method requires that the calling controller has been initialized.

Note that when integrating your controllers into an application, if you are dealing with DOM objects rather than HTML, then you can alternatively make use of method ERoot.attach, to inject and initialize controllers for one specific DOM element.

You should try to avoid use of synchronous bindings, if possible. The binding engine implements the logic of minimizing the number of checks against the DOM, but it works/scales best when requests are asynchronous.

Parameters:
Name Type Attributes Default Description
process boolean | function <optional>
false

Determines how to process the binding:

  • any falsy value (default): the binding will be done asynchronously;
  • a function: binding is asynchronous, calling the function when finished;
  • any truthy value, except a function type: forces synchronous binding.
Source:
See:
Example
app.addController('appCtrl', function(ctrl) {

    // You can also change content here, but
    // the binding only possible during onInit;

    ctrl.onInit = function() {
        // Injecting a new controlled element:
        ctrl.node.innerHTML = '<div e-bind="someCtrl"></div>';

        // Asynchronously bind all child controlled elements:
        ctrl.bind(function() {
            // Binding has finished, we can now find the controller:
            var c = ctrl.findOne('someCtrl');
            // and communicate with it:
            c.someMethod();
        });

        // The following binding would produce the same result:
        // app.bindFor(this.node, cb);
    };
});

depends(names)

Verifies that each controller in the list of dependencies exists, or else throws an error. It is normally used during the controller's construction.

This optional level of verification is mainly useful when using dynamically injected controllers (not just the ones through method extend), as it is best to verify such dependencies before trying to use them.

Note however, that this method may not see controllers registered dynamically.

Parameters:
Name Type Description
names Array.<CtrlName>

List of controller names. It should include all controller names that are due to be extended (via method extend), plus the ones that can be requested dynamically.

Trailing spaces are ignored.

Source:
See:
Example
app.addController('ctrlName', function(ctrl) {

    // Make sure every controller on the list is available,
    // or else throw a detailed dependency error:
    ctrl.depends(['appCtrl', 'mod.ctrl1']);

});

extend(names, localopt) → {EController|Array.<EController>}

Extends other controller(s) with new functionality, thus providing functional inheritance.

It creates and returns a new controller(s), according to the parameters. But if you specify a controller name that's already bound to the element, that controller is returned instead, to be reused, because only a single controller type can be bound to any given element.

This method can only be called during event onInit.

Note that while the calling controller has immediate access to extended controllers, as they are returned by the method, other/global controllers can communicate with them only during or after event onReady.

Parameters:
Name Type Attributes Default Description
names CtrlName | Array.<CtrlName>

Either a single controller name, or an array of names. Trailing spaces are ignored.

local boolean <optional>
false

When true, newly created controllers are not registered in the global map, so global search methods ERoot.find and ERoot.findOne would not find them. This offers a level of encapsulation / privacy, in case access to such extended controllers by an outside controller is undesirable.

Note that if the element already has the controller, it is reused, and flag local is then ignored.

Source:
See:
Returns:
  • if you pass in a single controller name, it returns a single controller.
  • if you pass in an array of names, it returns an array of controllers.
Type
EController | Array.<EController>
Example
app.addController('myController', function(ctrl) {
    // Optional early dependency diagnostics:
    ctrl.depends(['dragDrop', 'removable']);

    ctrl.onInit = function() {
        var c = ctrl.extend(['dragDrop', 'removable']);

        // c[0] = ctrl.node.controllers.dragDrop
        // c[1] = ctrl.node.controllers.removable
    };
});

find(name) → {Array.<EController>}

Searches for all initialized child controllers, by a given controller name, including the extended controllers.

This method searches through DOM, as it needs to iterate over child elements. And because of that, even though it searches just through a sub-set of elements, it is always slower than the global ERoot.find method.

It will find explicitly created controllers, if called during or after event onInit, and implicitly created controllers (extended via method extend), if called during or after event onReady.

Parameters:
Name Type Description
name CtrlName

Controller name to search by. Trailing spaces are ignored.

Source:
See:
Returns:

List of initialized child controllers.

Type
Array.<EController>

findOne(name) → {EController}

Implements a safe-check search for a single initialized child controller by a given controller name.

The method will throw an error, if multiple or no controllers found.

It will find explicitly created controllers, if called during or after event onInit, and implicitly created controllers (extended via method extend), if called during or after event onReady.

Parameters:
Name Type Description
name CtrlName

Controller name to search by. Trailing spaces are ignored.

Source:
See:
Returns:

A single child controller with the matching name.

Type
EController

Events

onDestroy

De-initialization event handler.

It signals the controller that its element has been removed from DOM, and it is time to release any pre-allocated resources, if necessary.

In any modern browser, the event is triggered immediately, courtesy of MutationObserver, while in older browsers (IE9 and IE10), it falls back on a manual background check that runs every second. You can make it instant under IE9/10 also, by adding one of the MutationObserver polyfills to the app.

Type:
  • function
Source:
See:
Example
app.addController('ctrlName', function(ctrl) {
   ctrl.onDestroy = function() {
       // this = ctrl

       // Release any resources here, if necessary
   };
});

onInit

Initialization event handler.

It represents the state of the controller when it is ready to do any of the following:

  • find explicitly bound (through e-bind attribute) controllers and communicate with them
  • extend the element with other controllers (via method extend)

Note that at this point you cannot locate or communicate with outside controllers being extended (via method extend). For that you need to use onReady event.

If a controller doesn't extend or communicate with other controllers, then it does not need to handle this event.

Type:
  • function
Source:
See:
Example
app.addController('ctrlName', function(ctrl) {
   ctrl.onInit = function() {
       // this = ctrl

       // - you can use ctrl.extend here, to extend it
       // - you can find explicitly created controllers
   };
});

onReady

Post-initialization event (happens after event onInit).

At this point you can find and communicate with controllers created implicitly, through extension (via method extend).

Controllers can only be extended during onInit, and they are initialized right after. If you need to find and communicate with such extended controllers, it is only possible during or after this event.

Type:
  • function
Source:
See:
Example
app.addController('ctrlName', function(ctrl) {
   ctrl.onReady = function() {
       // this = ctrl

       // you can find and communicate with all controllers here
   };
});