Skip to content

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

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"
  }
})

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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