marko/docs/widgets/taglib-api.md
Charlie Duong fc82ef0cf0 Deprecated w-on* attributes (#434)
Added support for on*() attributes.
2016-11-16 10:53:51 -08:00

6.5 KiB

Marko Widgets Taglib

Custom attributes

w-bind

This attribute is used to bind a widget to a DOM element.

Examples

Bind to a JavaScript module named ./widget.js that exports the widget definition:

<div w-bind="./widget">...</div>

Bind to a JavaScript module named ./widget.js or ./index.js (searched for in that order) that exports the widget definition:

<div w-bind>...</div>

ref

Used to assign a scoped ID to a nested widget or a nested DOM element. The ID will be a concatenation of the parent widget ID with the provided value of the ref.

Examples

Using ref with an HTML element

<div w-bind="./widget">
    <button ref="myButton" type="button">My Button</button>
</div>

This will produce output code similar to the following:

<div>
    <button id="w0-myButton" type="button">My Button</button>
</div>

The containing widget can reference the nested DOM element using the following code:

var myButton = this.getEl('myButton');

Using ref with a nested widget

<div w-bind="./widget">
    <app-button ref="myButton" label="My Button" />
</div>

This will produce output code similar to the following:

<div>
    <button id="w0-myButton" type="button">My Button</button>
</div>

The containing widget can reference the nested widget using the following code:

var myButton = this.getWidget('myButton');

w-on*

The w-on* can be used to declaratively bind event listeners to a DOM element or widget.

NOTE: For DOM events that bubble, efficient DOM event delegation will automatically be used to avoid attaching direct event listeners for performance reasons.

Examples

Using w-on* with a nested HTML element

<div w-bind="./widget">
    <button onClick("handleMyButtonClick") type="button">My Button</button>
</div>

When the button HTML element is clicked, the handleMyButtonClick method of the widget will be invoked:

module.exports = require('marko-widgets').defineComponent({
    // ...

    handleMyButtonClick: function(event, el) {
        // event will be the native DOM event
        // el will be the native DOM element
    }
})

The containing widget can reference the nested DOM element using the following code:

var myButton = this.getEl('myButton');

Using w-on* with a nested widget

<div w-bind="./widget">
    <app-button onSomeCustomEvent("handleSomeCustomEvent") label="My Button" />
</div>

For the example above it is assumed that the nested widget will emit the custom event using code similar to the following:

this.emit('handleSomeCustomEvent', { foo: bar });

no-update

Preserves the DOM subtree associated with the DOM element or widget such that it won't be modified or rerendered when rerendering the UI component.

Example:

<div>
    <table no-update> <!-- Don't ever rerender this table -->
        ...
    </table>
</div>
<div>
    <app-map no-update/> <!-- Don't ever rerender this UI component -->
</div>

no-update-if

Similar to no-update except that the DOM subtree is conditionally preserved:

<div>
    <table no-update-if(data.tableData == null)>
        ...
    </table>
</div>

no-update-body

Similar to no-update except that only the child DOM nodes are preserved:

<div no-update-body> <!-- Don't ever rerender any nested DOM elements -->
    ...
</div>

no-update-body-if

Similar to no-update-if except that only the child DOM nodes are preserved:

<div>
    <table no-update-if(data.tableData == null)>
        ...
    </table>
</div>

w-preserve-attrs

This custom attribute is used to prevent select DOM elements from being modified during a rerender:

<div w-preserve-attrs="class,style">
    ...
</div>

w-for

The w-for attribute is used to render a for attribute that references a scoped widget element:

<form>
    <label w-for="yes">Yes</label>
    <input type="radio" ref="yes" value="yes">

    <label w-for="no">No</label>
    <input type="radio" ref="no" value="no">
</form>

This will produce code similar to the following:

<form>
    <label for="w0-yes">Yes</label>
    <input type="radio" ref="w0-yes" value="yes">

    <label for="w0-no">No</label>
    <input type="radio" id="w0-no" value="no">
</form>

Custom tags

<init-widgets>

Generates the necessary code to initialize widgets associated with UI components rendered on the server.

Supported attributes:

  • immediate - If true then a <script> tag will be generated that immediately initializes all widgets instead of waiting for the "dom ready" event. For async fragments, a <script> will be inserted at the end of each async fragment.

Examples:

Non-immediate widget initialization

If the immediate attribute is not provided or set to false then widgets will initialize during the "dom ready" event. For example, given the following Marko code:

<init-widgets/>

This will produce output HTML code similar to the following:

<noscript id="markoWidgets" data-ids="w0,w1,w2"></noscript>

The <noscript> HTML tag is simply a container to keep an "index" of all of the IDs associated with UI components that have a widget that needs to be initialized. When the marko-widgets module initializes in the browser it will query for the #markoWidgets to discover all of the widget IDs.

Immediate widget initialization

If the immediate attribute is provided or set to true then widgets will initialize via inline JavaScript code added to the output HTML. For example, given the following Marko code:

<init-widgets immediate/>

This will produce output HTML code similar to the following:

<script>
/* REMOVED: serialized widget state and config */
$markoWidgets("w0,w1,w2")
</script>

When immediate widget initialization is enabled, widgets will be initialized before the DOM ready event. In addition, inline widget initialization code will be appended to each async fragment.

<widget-types>

Used to conditionally bind a widget:

<widget-types default="./widget" mobile="./widget-mobile"/>

<div w-bind=(data.isMobile ? 'default' : 'mobile')>
    ...
</div>

The <widget-types> can also be used to disabling binding of a widget:

<widget-types default="./"/>

<div w-bind=(data.includeWidget ? 'default' : null)>

</div>