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 · 1 comment

Comments

@justinbmeyer
Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor Author

commented Jan 25, 2019

var fn = function(data, nodeList){
	var renderer = stache('<div>Hi</div>')
	return renderer( new Scope.LetContext({abc: data}), nodeList )
}
fn[can.isView] = true;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.