Skip to content

inline partials replace slots and templates and are passed to the ViewModel #323

@justinbmeyer

Description

@justinbmeyer

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:

  1. Make templates available to the view
  2. Call these templates with call expressions like template()
  3. 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"
  }
})

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions