can.Component
2.0Create widgets that use a template, a view-model and custom tags.
< TAG [ATTR-NAME="{KEY}|ATTR-VALUE"] > 2.1
Create an instance of a component on a particular tag in a can.stache template.
Parameters
-
TAG
{String}
An HTML tag name that matches the tag property of the component.
-
ATTR-NAME
{String}
An HTML attribute name. Any attribute name is valid. Any attributes added to the element are added as properties to the component's viewModel. In the DOM, attribute names are case insensitive. To pass a camelCase attribute to the component's viewModel, hypenate the attribute name like:
<tag attr-name="{key}"></tag>
This will set
attrName
on the component's viewModel. -
KEY
{key}
OptionalSpecifies the value of a property passed to the component instance's viewModel that will be looked up in the can.stache scope.
-
ATTR-VALUE
{key}
OptionalIf the attribute value is not wrapped with
{}
, the string value of the attribute will be set on the component's viewModel.
< TAG [ATTR-NAME=KEY|ATTR-VALUE] >
Create an instance of a component on a particular tag in a can.mustache template.
Parameters
-
TAG
{String}
An HTML tag name that matches the tag property of the component.
-
ATTR-NAME
{String}
An HTML attribute name. Any attribute name is valid. Any attributes added to the element are added as properties to the component's viewModel.
-
ATTR-VALUE
{key}
OptionalSpecifies the value of a property passed to the component instance's viewModel. By default
ATTR-VALUE
values are looked up in the [can.view.viewModel can.mustache viewModel]. If the string value of theATTR-NAME
is desired, this can be specified like:ATTR-NAME: "@"
-
KEY
{key}
OptionalSpecifies the value of a property passed to the component instance's viewModel that will be looked up in the can.stache scope.
Use
Watch this video for an overview of can.Component, why you should use it, and a hello world example:
This video provides a more in depth overview of the API and goes over several examples of can.Components:
Note: the videos above reference the
scope
property, which was replaced by the viewModel property in 2.2.To create a
can.Component
, you must first extendcan.Component
with the methods and properties of how your component behaves:This element says "Click me" until a user clicks it and then says "Hello There!". To create a a instance of this component on the page, add
<hello-world></hello-world>
to a mustache template, render the template and insert the result in the page like:Check this out here:
Typically, you do not append a single component at a time. Instead, you'll render a template with many custom tags like:
Creating a can.Component
Use can.Component.extend to create a
can.Component
constructor function that will automatically get initialized whenever the component's tag is found.Note that inheriting from components works differently than other CanJS APIs. You can't call
.extend
on a particular component to create a "subclass" of that component.Instead, components work more like HTML elements. To reuse functionality from a base component, build on top of it with parent components that wrap other components in their template and pass any needed viewModel properties via attributes.
Tag
A component's tag is the element node name that the component will be created on.
The following matches
<hello-world>
elements.Template
A component's template is rendered as the element's innerHTML.
The following component:
Changes
<hello-world></hello-world>
elements into:Use the
<content/>
tag to position the custom element's source HTML.The following component:
Changes
<hello-world>Hi There</hello-world>
into:viewModel
A component's viewModel defines a can.Map that is used to render the component's template. The maps properties are typically set by attributes on the custom element's HTML. By default, every attribute's value is looked up in the parent viewModel of the custom element and added to the viewModel object.
The following component:
Changes the following rendered template:
Into:
Default values can be provided. The following component:
Changes the following rendered template:
Into:
If you want to set the string value of the attribute on viewModel, give viewModel a default value of "@". The following component:
Changes the following rendered template:
Into:
Events
A component's events object is used to listen to events (that are not listened to with view bindings). The following component adds "!" to the message every time
<hello-world>
is clicked:Components have the ability to bind to special inserted and removed events that are called when a component's tag has been inserted into or removed from the page.
Helpers
A component's helpers object provides mustache helper functions that are available within the component's template. The following component only renders friendly messages:
Differences between components in can.mustache and can.stache
A can.mustache template passes values from the viewModel to a
can.Component
by specifying the key of the value in the attribute directly. For example:With can.stache, you wrap the key with
{}
. For example:If the key was not wrapped, the template would render:
Because the attribute value would be passed as the value of
greeting
.Examples
Check out the following examples built with
can.Component
.Tabs
The following demos a tabs widget. Click "Add Vegetables" to add a new tab.
An instance of the tabs widget is created by creating
<tabs>
and<panel>
elements like:To add another panel, all we have to do is add data to
foodTypes
like:The secret is that the
<panel>
element listens to when it is inserted and adds its data to the tabs' list of panels with:TreeCombo
The following tree combo lets people walk through a hierarchy and select locations.
The secret to this widget is the viewModel's
breadcrumb
property, which is an array of items the user has navigated through, andselectableItems
, which represents the children of the last item in the breadcrub. These are defined on the viewModel like:When the "+" icon is clicked next to each item, the viewModel's
showChildren
method is called, which adds that item to the breadcrumb like:Paginate
The following example shows 3 widget-like components: a grid, next / prev buttons, and a page count indicator. And, it shows an application component that puts them all together.
This demo uses a
Paginate
can.Map to assist with maintaining a paginated state:The
app
component creates an instance of thePaginate
model and awebsitesDeferred
that represents a request for the Websites that should be displayed.The
app
control passes paginate, paginate's values, and websitesDeferreds to its sub-components:IE 8 Support
While CanJS does support Internet Explorer 8 out of the box, if you decide to use
can.Component
then you will need to include HTML5 Shiv in order for your custom tags to work properly.For namespaced tag names (e.g.
<can:example>
) and hyphenated tag names (e.g.<can-example>
) to work properly, you will need to use version 3.7.2 or later.