-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Labels
Description
tldr Lets make something a little bit easier to use than partials.
Older ideas #322
Problem
1. Slots and partials use a lot of syntax that is unlike anything else in CanJS. The syntax is also noisy.
Here's how it looks to pass two templates:
<my-email>
<can-template name="subject">
<h1>{{this.subject}}</h1>
</can-template>
<can-template name="body">
<span>{{this.body}}</span>
</can-template>
</my-email>
And to call those templates:
view: `
<can-slot name="subject" subject:from="subject" />
<can-slot name="body" subject:from="body" />
`
2. Folks want access to these templates
Someone (I wrote it on behalf of someone else) wanted the ability to pass templates down: #147
like:
<sub-component>
<can-template name="childName" from="view.templates.templateName"/>
</sub-component>
It's also odd that <can-template>
s are not available to the ViewModel as these are essentially arguments to the components similar to from:
would be.
Solution
Lets:
- Make templates available to the view
- Call these templates with call expressions like
template()
- Reuse syntax already available to define them.
I propose something like the following:
<my-email>
{{<subjectView}}
<h1>{{this.subject}}</h1>
{{/subjectView}}
{{<bodyView}}
<span>{{this.body}}</span>
{{/bodyView}}
</my-email>
Component.extend({
tag: "my-email",
view: `
{{ this.subjectView( subject = this.subject ) }}
{{ this.bodyView( body = this.body ) }}
`,
ViewModel: {
subjectView: "any",
bodyView: "any"
}
})
How it solves: Slots and partials use a lot of syntax that is unlike anything else in CanJS. The syntax is also noisy.
- This uses inline partials, another syntax, there's less to learn.
- This uses call expressions to call renderers
- There's less overall text
How it solves: Folks want access to these templates
My-email could pass along these partials like:
Component.extend({
tag: "my-email",
view: `
<my-subject subjectView:from="this.subjectView" subject:from="this.subject"/>
{{ this.bodyView( body = this.body ) }}
`,
ViewModel: {
subjectView: "any",
bodyView: "any"
}
})
Other Considerations
Handling default content
Default content can be handled one of two ways:
// CONDITIONAL CHECKS
Component.extend({
tag: "my-email",
view: `
{{# if(this.subjectView) }}
{{ this.subjectView( subject = this.subject ) }}
{{else}}
DEFAULT CONTENT
{{/if}}
{{ this.bodyView( body = this.body ) }}
`,
ViewModel: {
subjectView: "any",
bodyView: "any"
}
})
OR
// Default VM properties
Component.extend({
tag: "my-email",
view: `
{{ this.subjectView( subject = this.subject ) }}
{{ this.bodyView( body = this.body ) }}
`,
ViewModel: {
subjectView: {
type: stache,
value: `DEFAULT CONTENT`
},
bodyView: "any"
}
})
matthewp, green3g and phillipskevin