DoneJS StealJS jQuery++ FuncUnit DocumentJS
5.33.3
6.0.0 4.3.0 3.14.1 2.3.35
  • About
  • Guides
  • API Docs
  • Community
  • Contributing
  • Bitovi
    • Bitovi.com
    • Blog
    • Design
    • Development
    • Training
    • Open Source
    • About
    • Contact Us
  • About
  • Guides
  • API Docs
    • Observables
      • can-bind
      • can-compute
      • can-debug
      • can-define
      • can-define/list/list
      • can-define/map/map
      • can-define-backup
      • can-define-stream
      • can-define-stream-kefir
      • can-event-queue
      • can-kefir
      • can-list
      • can-map
      • can-map-compat
      • can-map-define
      • can-observable-array
      • can-observable-object
      • can-observation
      • can-observation-recorder
      • can-observe
      • can-simple-map
      • can-simple-observable
      • can-stream
      • can-stream-kefir
      • can-value
    • Views
      • can-attribute-observable
      • can-component
        • define
          • extend
          • tag
          • view
          • ViewModel
        • create
          • <tag bindings...>
          • new Component
        • elements
          • <can-slot>
          • <can-template>
        • lifecycle hooks
          • connectedCallback
        • deprecated
          • beforeremove
          • <content>
          • events
          • helpers
          • leakScope
          • viewModel
      • can-stache
      • can-stache-bindings
      • can-stache-converters
      • can-stache-element
      • can-stache-route-helpers
      • can-view-autorender
      • can-view-callbacks
      • can-view-import
      • can-view-live
      • can-view-model
      • can-view-nodelist
      • can-view-parser
      • can-view-scope
      • can-view-target
      • steal-stache
    • Data Modeling
      • can-connect
      • can-connect-feathers
      • can-connect-ndjson
      • can-connect-tag
      • can-fixture
      • can-fixture-socket
      • can-local-store
      • can-memory-store
      • can-ndjson-stream
      • can-query-logic
      • can-realtime-rest-model
      • can-rest-model
      • can-set-legacy
      • can-super-model
    • Routing
      • can-deparam
      • can-param
      • can-route
      • can-route-hash
      • can-route-mock
      • can-route-pushstate
    • JS Utilities
      • can-assign
      • can-define-lazy-value
      • can-diff
      • can-globals
      • can-join-uris
      • can-key
      • can-key-tree
      • can-make-map
      • can-parse-uri
      • can-queues
      • can-string
      • can-string-to-any
      • can-zone-storage
    • DOM Utilities
      • can-ajax
      • can-attribute-encoder
      • can-child-nodes
      • can-control
      • can-dom-data
      • can-dom-events
      • can-dom-mutate
      • can-event-dom-enter
      • can-event-dom-radiochange
      • can-fragment
    • Data Validation
      • can-define-validate-validatejs
      • can-type
      • can-validate
      • can-validate-interface
      • can-validate-legacy
      • can-validate-validatejs
    • Typed Data
      • can-cid
      • can-construct
      • can-construct-super
      • can-data-types
      • can-namespace
      • can-reflect
      • can-reflect-dependencies
      • can-reflect-promise
      • can-types
    • Polyfills
      • can-symbol
      • can-vdom
    • Core
    • Infrastructure
      • can-global
      • can-test-helpers
    • Ecosystem
    • Legacy
  • Community
  • Contributing
  • GitHub
  • Twitter
  • Chat
  • Forum
  • News
Bitovi

<can-slot>

  • Edit on GitHub

Position the content of <can-template> elements.

<can-slot name='NAME' BINDINGS>DEFAULT_CONTENT</can-slot>

<can-slot> and <can-template> are used together to customize the layout of a component.

<can-slot> renders a matching <can-template name='name'/> element from the LIGHT_DOM, or if there is no matching <can-template>, renders the DEFAULT_CONTENT instead.

For example, the following <my-counter> component allows users to customize the button that increments the count:

<my-app></my-app>
<script type="module">
import {Component} from "can";

Component.extend({
  tag: "my-counter",
  view: `
      <form on:submit="this.increment(scope.event)">
          Count: <span>{{this.count}}</span>

          <can-slot name="incrementButton"/>
      </form>
  `,
  ViewModel: {
      count: {type: "number", default: 0},
      increment(event) {
          event.preventDefault();
          this.count++;
      }
  }
});


Component.extend({
  tag: "my-app",
  view: `
      <my-counter>
          <can-template name="incrementButton">
              <button>Add One</button>
          </can-template>
      </my-counter>
  `
});
</script>

Parameters

  1. NAME {String}:

    The name of the <can-template> to render in place of the <can-slot>.

  2. BINDINGS {can-stache-bindings}:

    You can pass values to the <can-template>. The following passes count as number to <can-template name="displayCount">:

    <my-app></my-app>
    <script type="module">
    import {Component} from "can";
    
    Component.extend({
      tag: "my-counter",
      view: `
          <form on:submit="this.increment(scope.event)">
              <can-slot name="displayCount"
                  number:from="this.count" />
    
              <can-slot name="incrementButton" />
          </form>
      `,
      ViewModel: {
          count: {type: "number", default: 0},
          increment(event) {
              event.preventDefault();
              this.count++;
          }
      }
    });
    
    
    Component.extend({
      tag: "my-app",
      view: `
          <my-counter>
              <can-template name="displayCount">
                  Your number is <b>{{number}}</b>
              </can-template>
              <can-template name="incrementButton">
                  <button>Add One</button>
              </can-template>
          </my-counter>
      `
    });
    </script>
    
    

    The key:from, key:to and key:bind bindings all work.

    NOTE: You are also able to set the this of the template like: this:from="value". This is an older way of passing values and should be avoided.

  3. DEFAULT_CONTENT {sectionRenderer(context, helpers)}:

    The content that should be used if there is no content in the matching <can-template>.

    The following provides a default displayCount. Notice that there is no displayCount <can-template>:

    <my-app></my-app>
    <script type="module">
    import {Component} from "can";
    
    Component.extend({
        tag: "my-counter",
        view: `
            <form on:submit="this.increment(scope.event)">
                <can-slot name="displayCount"
                    number:from="this.count">
                    Count: {{this.count}}
                </can-slot>
    
                <can-slot name="incrementButton" />
            </form>
        `,
        ViewModel: {
            count: {type: "number", default: 0},
            increment(event) {
                event.preventDefault();
                this.count++;
            }
        }
    });
    
    Component.extend({
        tag: "my-app",
        view: `
            <my-counter>
                <can-template name="incrementButton">
                    <button>Add One</button>
                </can-template>
            </my-counter>
        `
    });
    </script>
    
    

Use

<can-slot> and <can-template> are used together to customize the layout of a component.

<can-template> is used to provide custom layout to a component. <can-slot> positions that layout within a component's view. One way to think about it is that <can-template> is an argument to a component. Component uses <can-slot> to look up that argument and use it.

<can-template> and <can-slot>s must have a name attribute like:

<can-template name="someName">...</can-template>

<can-slot name="someName">...</can-slot>

Those names are used to match a <can-slot> to a user provided <can-template>.

For example, <can-template name="incrementButton"> passes an incrementButton template to the <my-counter> element below:

<my-app></my-app>
<script type="module">
import {Component} from "can";

Component.extend({
    tag: "my-counter",
    view: `
        <form on:submit="this.increment(scope.event)">
            Count: <span>{{this.count}}</span>

            <can-slot name="incrementButton"/>
        </form>
    `,
    ViewModel: {
        count: {type: "number", default: 0},
        increment(event) {
        event.preventDefault();
            this.count++;
        }
    }
});


Component.extend({
    tag: "my-app",
    view: `
        <my-counter>
            <can-template name="incrementButton">
                <button>Add One</button>
            </can-template>
        </my-counter>
    `
});
</script>

Passing values

By default, <can-template>s are rendered with the same scope as the surrounding content. For example, {{this.word}} is available but {{count}} is not:

<my-app></my-app>
<script type="module">
import {Component} from "can";

Component.extend({
    tag: "my-counter",
    view: `
        <form on:submit="this.increment(scope.event)">
        <can-slot name="displayCount"/>

        <button>+1</button>
        </form>
    `,
    ViewModel: {
        count: {type: "number", default: 0},
        increment(event) {
            event.preventDefault();
            this.count++;
        }
    }
});

Component.extend({
    tag: "my-app",
    view: `
        <my-counter>
            <can-template name="displayCount">
                Your {{this.word}} is <b>{{count}}</b>
            </can-template>
        </my-counter>
    `,
    ViewModel: {
        word: {default: "number"}
    }
});
</script>

You can use key:from or key:bind to pass values to the <can-template>'s content. The following passes count as number to <can-template name="displayCount">:

<my-app></my-app>
<script type="module">
import {Component} from "can";

Component.extend({
    tag: "my-counter",
    view: `
        <form on:submit="this.increment(scope.event)">
            <can-slot name="displayCount"
                number:from="this.count" />

            <button>+1</button>
        </form>
    `,
    ViewModel: {
        count: {type: "number", default: 0},
        increment(event) {
            event.preventDefault();
            this.count++;
        }
    }
});

Component.extend({
    tag: "my-app",
    view: `
        <my-counter>
            <can-template name="displayCount">
                Your {{this.word}} is <b>{{number}}</b>
            </can-template>
        </my-counter>
    `,
    ViewModel: {
        word: {default: "number"}
    }
});
</script>

Functions can be passed to. The following shows passing <my-counter>'s add method:

<my-app></my-app>
<script type="module">
import {Component} from "can";

Component.extend({
    tag: "my-counter",
    view: `
        <can-slot name="incrementButton"
            add:from="this.add"/>
        <can-slot name="countDisplay"
            count:from="this.count"/>
    `,
    ViewModel: {
        count: {type: "number", default: 0},
        add(increment){
            this.count += increment;
        }
    }
});


Component.extend({
    tag: "my-app",
    view: `
        <my-counter count:from="5">
            <can-template name="incrementButton">
                <button on:click="add(5)">ADD 5!</button>
            </can-template>
            <can-template name="countDisplay">
                You have counted to {{count}}!
            </can-template>
        </my-counter>
    `
});
</script>

CanJS is part of DoneJS. Created and maintained by the core DoneJS team and Bitovi. Currently 5.33.3.

On this page

Get help

  • Chat with us
  • File an issue
  • Ask questions
  • Read latest news