<can-slot>
<can-slot name='NAME' BINDING>DEFAULT_CONTENT</can-slot>
Replaces any <can-slot name='NAME' /> element found in a component's view with the rendered contents
of the <can-template /> element from the LIGHT_DOM that has a matching [TEMPLATE_NAME] attribute. Uses the scope of
the LIGHT_DOM by default.
import Component from "can-component";
import stache from "can-stache";
Component.extend( {
tag: "my-email",
view: `
<can-slot name="subject" />
`
} );
const renderer = stache(`
<my-email>
<can-template name="subject">
{{subject}}
</can-template>
</my-email>
`);
renderer( {
subject: "Hello World"
} );
//-> <my-email>Hello World</my-email>
Parameters
- NAME
{String}:The name of the <can-template> to render in place of the
<can-slot>. - BINDING
{can-stache-bindings}:You can bind to the context (also known as this) of of the corresponding <can-template>. This lets you pass data to the template. The following passes
userasthisto the corresponding<can-template name="user-details">:<can-slot name="user-details" this:from="user">toChild:from, toParent:to and twoWay:bind with
thisall work. - DEFAULT_CONTENT
{sectionRenderer(context, helpers)}:The content that should be used if there is no content in the matching
<can-template>.
Use
To use <can-slot> we can create a Component that has <can-slot> elements in it's view
and render that component with <can-template> elements in the LIGHT_DOM.
Any <can-slot> that has a name attribute matching the name attribute of a <can-template> will be
replaced by the rendered inner contents of the <can-template>.
import Component from "can-component";
import stache from "can-stache";
Component.extend( {
tag: "my-email",
view: `
<can-slot name="subject" />
<p>My Email</p>
<can-slot name="body" />
`
} );
const renderer = stache(`
<my-email>
<can-template name="subject">
<h1>{{subject}}</h1>
</can-template>
<can-template name="body">
<span>{{body}}</span>
</can-template>
</my-email>
`);
renderer( {
subject: "Hello World",
body: "The email body"
} );
/*
<my-email>
<h1>Hello World</h1>
<p>My Email</p>
<span>The email body</span>
</my-email>
*/
Passing context
Context (this) can be bound to and passed to a template. The following
passes <my-email>'s subject and body to the subject and body templates. Notice
how subject and body are read by {{this}}.
import Component from "can-component";
import stache from "can-stache";
Component.extend( {
tag: "my-email",
view: `
<can-slot name="subject" this:from="subject" />
<can-slot name="body" this:from="body" />
`,
ViewModel: {
subject: {
default: "Hello World"
},
body: {
default: "Later Gator"
}
}
} );
const renderer = stache(`
<my-email>
<can-template name="subject">
<h1>{{this}}</h1>
</can-template>
<can-template name="body">
<span>{{this}}</span>
</can-template>
</my-email>
`);
const testView = renderer( {
subject: "Hello World",
body: "This is a greeting."
} );
/*
<my-email>
<h1>Hello World</h1>
<p>This is a greeting.</p>
</my-email>
*/
Default content
Default content can be specified to be used if there is no matching <can-template>
or the matching <can-template> has no inner content.
import Component from "can-component";
import stache from "can-stache";
Component.extend( {
tag: "my-email",
view: `
<can-slot name="subject">
<p>This is the default {{subject}}</p>
</can-slot>
`
} );
const renderer = stache(`
<my-email>
<can-template name="subject" />
</my-email>
`);
const testView = renderer( {
subject: "content"
} );
/*
<my-email>
<p>This is the default content</p>
</my-email>
*/