Custom elements and widgets
JavaScript HTML

readme.md

can-component

Build Status

Custom elements for CanJS.

API

can-component

Create widgets that use a template, a view-model and custom tags.

< TAG BINDINGS... >

Create an instance of a component on a particular tag in a [can-stache] template. In 2.3, use the [can-stache-bindings bindings] syntaxes to set up bindings.

  1. TAG {String}: An HTML tag name that matches the tag property of the component.

  2. BINDINGS {can-stache-bindings}: Use the following binding syntaxes to connect the component’s viewModel to the template’s [can-view-scope scope]:

    • [can-stache-bindings.toChild]=[can-stache.key] — one-way binding to child
    • [can-stache-bindings.toParent]=[can-stache.key] — one-way binding to parent
    • [can-stache-bindings.twoWay]=[can-stache.key] — two-way binding child to parent

    Example:

    <my-tag {to-child}="key" 
            {^to-parent}="key" 
            {(two-way)}="key"></my-tag>
    

Component.extend(proto)

Extends the can-component constructor function with prototype properties and methods.

  1. proto {Object}: An object set as the prototype of the constructor function. You will typically provide the following values on the prototype object.

tag {String}

Specifies the HTML tag (or node-name) the can-component will be created on.

String

The tag name the can-component will be created on. Tag names are typically lower cased and hyphenated like: foo-bar. Components register their tag with [can-view-callbacks.tag tag].

template {can-stache.renderer|String}

Provides a template to render directly within the component’s tag. The template is rendered with the component’s viewModel. <content> elements within the template are replaced by the source elements within the component’s tag.

can-stache.renderer

A [can-stache.renderer] returned by [can-stache]. For example:

Component({
  tag: "my-tabs",
  template: stache("<ul>{{#panels}}<li>{{title}}</li> ...")
})
String

The string contents of a [can-stache] template. For example:

Component({
  tag: "my-tabs",
  template: "<ul>{{#panels}}<li>{{title}}</li> ..."
})

Note: Using mustache is deprecated. Please switch to [can-stache].

viewModel {Object|can-map|function(attrs, [parentScope](#-tag-bindings-), element)}

Provides or describes a [can-map] constructor function or Map instance that will be used to retrieve values found in the component’s template. The map instance is initialized with values specified by the component element’s attributes.

Note: This page documents behavior of components in [can-stache]. [can-mustache] behaves slightly differently. If you want the behavior of components with [can-mustache], please look at versions of this page prior to 2.3. In 2.3, use [can-stache-bindings] [can-stache-bindings.toChild], [can-stache-bindings.toParent] and [can-stache-bindings.twoWay] to setup viewModel bindings.

Object

A plain JavaScript object that is used to define the prototype methods and properties of [can-construct constructor function] that extends [can-map]. For example:

Component.extend({
  tag: "my-paginate",
  viewModel: {
    offset: 0,
    limit: 20,
    next: function(){
      this.attr("offset", this.offset + this.limit);
    }
  }
});
can-map

A Map constructor function will be used to create an instance of the observable Map placed at the head of the template’s viewModel. For example:

var Paginate = Map.extend({
  offset: 0,
  limit: 20,
  next: function(){
    this.attr("offset", this.offset + this.limit);
  }
})
Component.extend({
  tag: "my-paginate",
  viewModel: Paginate
})
function(attrs, parentScope, element)

Returns the instance or constructor function of the object that will be added to the viewModel.

  1. attrs {Object}: An object of values specified by the custom element’s attributes. For example, a template rendered like:

    stache("<my-element title='name'></my-element>")({
      name: "Justin"
    })
    

    Creates an instance of following control:

    Component.extend({
      tag: "my-element",
      viewModel: function(attrs){
        attrs.title //-> "Justin";
        return new Map(attrs);
      }
    })
    

    And calls the viewModel function with attrs like {title: "Justin"}.

  2. parentScope {can-component|:|:|viewModel}:

    The viewModel the custom tag was found within. By default, any attribute’s values will be looked up within the current viewModel, but if you want to add values without needing the user to provide an attribute, you can set this up here. For example:

    Component.extend({
      tag: "my-element",
      viewModel: function(attrs, parentScope){
        return new Map({title: parentScope.attr('name')});
      }
    });
    

    Notice how the attribute’s value is looked up in my-element’s parent viewModel.

  3. element {HTMLElement}: The element the can-component is going to be placed on. If you want to add custom attribute handling, you can do that here. For example:

    Component.extend({
      tag: "my-element",
      viewModel: function(attrs, parentScope, el){
        return new Map({title: el.getAttribute('title')});
      }
    });
    
  • returns {can-map|Object}: Specifies one of the following:

    • The data used to render the component’s template.
    • The prototype of a Map that will be used to render the component’s template.

events {Object\<can-control.eventDescription,can-control.eventHandler\>}

Listen to events on elements and observables.

Object<can-control.eventDescription,can-control.eventHandler>

An object of event names and methods that handle the event. For example:

Component({
  events: {
    ".next click": function(){
      this.viewModel.next()
    }
  },
  viewModel: {
    next: function(){
      this.attr("offset", this.offset + this.limit);
    }
  }
})

A component’s events object is used as the prototype of a [can-control]. The control gets created on the component’s element. The component’s viewModel is available within event handlers as this.viewModel.

helpers {Object\<String,can-stache.helper\>}

Helper functions used with the component’s template.

Object<String,can-stache.helper>

An object of [can-stache] helper names and methods. The helpers are only available within the component’s template and source html. Helpers are always called back with this as the viewModel.

leakScope {Boolean}

Allow reading the outer scope values from a component’s template and a component’s viewModel values in the user content.

Boolean

false limits reading to:

  • the component’s viewModel from the component’s template, and
  • the outer scope values from the user content.

true adds the ability to read:

  • the outer [can-view-scope scope] values from the component’s template, and
  • the component’s viewModel values from the user content.

The default value is true. This may reverse in 3.0.

Contributing

Making a Build

To make a build of the distributables into dist/ in the cloned repository run

npm install
node build

Running the tests

Tests can run in the browser by opening a webserver and visiting the test.html page. Automated tests that run the tests from the command line in Firefox can be run with

npm test