Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
justinbmeyer opened this issue Dec 12, 2018 · 2 comments

Comments

@justinbmeyer
Copy link
Contributor

justinbmeyer commented Dec 12, 2018

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"
  }
})
@justinbmeyer
Copy link
Contributor Author

var fn = function(data, nodeList){
	var renderer = stache('<div>Hi</div>')
	return renderer( new Scope.LetContext({abc: data}), nodeList )
}
fn[can.isView] = true;

@rjgotten
Copy link

rjgotten commented Jun 16, 2020

For what it's worth; I hate the inline partial syntax. The tag-based slot/template syntax is far more friendly on the eyes.

Objectively speaking, replacing a clear landmark name such as can-slot or can-template with a generic looking call expression and replacing the default inner content with a generic {{#if}} section helper is terrible for discoverability.

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

No branches or pull requests

3 participants