|
The Infusion Framework automatically creates a DOM Binder for any View Component as it constructs and attaches it to the component as a top-level member named dom
. View Components specify a set of names selectors in the component's defaults called selectors:
fluid.defaults("fluid.newComponent", { gradeNames: ["fluid.viewComponent", "autoInit"], selectors: { uiBit1: ".className1", uiBit2: ".className2" } }); |
DOM elements related to this component can be resolved declaratively using the dom
member. For example, if {newComponent}
is a reference to an instance of the above component, a reference to one of its DOM binder elements as declared above could be written as {newComponent}.dom.uiBit1.
The full programmatic API to the DOM binder also available through this dom
member (see DOM Binder API for information about available methods). For convenience, the DOM Binder's locate()
function is also added to the component as a top-level instance member.
Unless they are otherwise qualified, all searches performed by the DOM binder attached to a particular component will be automatically scoped to the component's own container.
The preferred way of using the DOM binder to access a component's DOM elements is through declarative configuration, using the form "{<componentRef>}.dom.<selectorName>"
. These references typically occur in the component's default configuration specification, but references may also be made from any other component.
In the following example, the component's default configuration assigns a DOM element to another top-level component member using the members
option:
fluid.defaults("fluid.tutorials.buttonHolder", { gradeNames: ["fluid.viewComponent", "autoInit"], selectors: { button: ".button" }, members: { button: "{that}.dom.button" } }); |
Declarative configuration is also the preferred approach for supplying arguments to Invokers and Event Listeners, as shown in the following example:
fluid.defaults("fluid.tutorials.buttonHolder", { gradeNames: ["fluid.viewComponent", "autoInit"], selectors: { status: ".holder-status", indicator: ".holder-ind" }, events: { onSelect: null }, listeners: { onSelect: { funcName: "fluid.tutorials.buttonHolder.selectHandler", args: ["{that}.dom.indicator", "arguments.0"] } }, invokers: { highlightStatus: { funcName: "fluid.tutorials.buttonHolder.highlight", args: ["{that}.dom.status"] } } }); |
Standard programmatic access to the DOM binder is available using the locate()
function:
that.locate(name); |
The locate()
method retrieves the specified DOM node by querying the DOM.
(For information about parameters for this and other DOM Binder functions, see DOM Binder API.)
The other methods on the DOM Binder are less frequently used, and are not attached to the top-level component in the way that locate()
is. They need to be accessed through the DOM Binder's own object available as that.dom
.
that.dom.fastLocate(name); |
The fastLocate()
method retrieves the DOM node from the DOM Binder's cache instead of querying the DOM directly: When fastLocate()
is used instead of locate()
, if the results of the search are already present in the DOM binder's cache, they will be returned directly without searching the DOM again. This can be very much more rapid, but runs the risk of returning stale results. The DOM binder's cache is populated for a query whenever a query is submitted via locate()
.
that.dom.clear() |
The clear()
method completely clears the cache for the DOM binder for all queries. It should be used whenever, for example, the container's markup is replaced completely, or otherwise is known to change in a wholesale way.
that.dom.refresh(names); |
The refresh()
method refreshes the cache for one or more selector names, ready for subsequent calls to fastLocate()
. It functions exactly as for a call to locate()
except that
refresh
rather than just a single one.The Inline Edit component requires three parts in its user interface:
The component declares selector names for these elements, and provides defaults, in its call to fluid.defaults()
:
fluid.defaults("fluid.inlineEdit", { selectors: { text: ".text", editContainer: ".editContainer", edit: ".edit" }, .... |
Here, the default selectors use class names. To use these defaults, an implementer can simply attach these class names to the relevant elements in mark-up. Alternatively, the implementer may choose to override some or all of these selectors with other selectors. For example:
var myOpts = { selectors: { text: "#display-text", edit: "#edit-field" } }; var myIEdit = fluid.inlineEdit(myContainer, myOpts); |
In this example, the implementer is using element IDs to identify the text and edit fields. (Because a custom editContainer
is not supplied, it will default to the selector .editContainer
declared by the component.)
To access the DOM elements, the Inline Edit component uses its DOM Binder and the selector names:
that.viewEl = that.locate("text"); that.editContainer = that.locate("editContainer"); that.editField = that.locate("edit", that.editContainer); |
In this way, the Inline Edit component is completely ignorant of the markup it is working with, or even the selectors used. When the markup changes, code doesn't break.