What's the best way to pass a model to a component?

When developing components that interact with a model, in order to pass the model into the component, I’m currently setting up the model on the parent component’s viewModel and passing it in as an attribute on the child component. Here’s a pseudo-code/abbreviated example:

// parent-component viewModel
import TxnModel from 'app-name/models/transaction';
viewModel: {
  TxnModel
};
<parent-component>
  <child-component {model}="TxnModel"></child-component>
</parent-component>

This is working just fine, but I’d like to see a way to import the model directly in the template, since in most cases I don’t really need it in the parent component. Is there an existing way to do this?

<parent-component>
  <can-import from="app-name/models/transaction" as="TxnModel">
  <child-component {model}="TxnModel"></child-component>
</parent-component>

Also, I’d prefer to use the adjacent (non-nested) structure, to avoid the async “pyramid of doom” in the html markup:

<parent-component>
    <can-import from="app-name/models/transaction">
        <child-component {model}="value"></child-component>
    </can-import>
</parent-component>

Yes. I think @matthewp made another forum post about this. I’m on my cell so can’t easily search.

Basically you can export from an import with the normal view binding syntaxes to a reference scope.

Cool. Thanks. I’ll look for it.

I think it might be this one: Using 2.3 binding syntax to import and use partials

Does this mean that I should be able to do this:

<parent-component>
  <can-import from="app-name/models/transaction" {^value}="*TxnModel">
  <child-component {model}="TxnModel"></child-component>
</parent-component>

Or would I need to use the * to pass it into the child-component? Like this:

<child-component {model}="*TxnModel"></child-component>

Also, help me understand this better. Should the asterisk in *TxnModel make the TxnModel variable available to a “distant cousin” component, like in this example:

<parent-component>
  <can-import from="app-name/models/transaction" {^value}="*TxnModel">
  <child-component {model}="TxnModel"></child-component>
</parent-component>
<distant-cousin {model}="TxnModel"></distant-cousin>

Or would I need to use ../ in some way to get it out to that level: {^value}="../*TxnModel" to get it up another level?

@marshallswain *REF keys are references to a template variables:

https://canjs.com/docs/can.stache.key.html#section_templatevariableoperator_

https://canjs.com/docs/can.view.bindings.reference.html

There’s one context for variables for the entire template. This means there’s only one *TxnModel allowed for everything.

Because you are exporting a function, you might need the @ symbol to keep stache from running the function and getting its return value. Making your template look like:

<can-import from="app-name/models/transaction" {^@value}="*TxnModel">
<parent-component>
  <child-component {model}="@*TxnModel"></child-component>
</parent-component>
<distant-cousin {model}="@*TxnModel"></distant-cousin>

It looks like with a generated SuperModel, since it exports both a default export and connection, this is the syntax you have to use. It’s pretty much the same as what you posted. Thank for your help.

<can-import from="app-name/models/transaction" {^@value}="*TxnModel">
<parent-component>
  {{#if *TxnModel}}
    <child-component {model}="@*TxnModel.default"></child-component>
  {{/if}}
</parent-component>

{{#if *TxnModel}}
  <distant-cousin {model}="@*TxnModel.default"></distant-cousin>
{{/if}}

Here is what worked for me:

<can-import from="~/models/biggest-movers" {^value.default}="*BiggestMovers" />

<biggest-movers-grid {model}="*BiggestMovers"/>

testing:

> canViewModel('biggest-movers-grid').model
function BiggestMovers(){return __.apply(this,arguments)}

> new canViewModel('biggest-movers-grid').model( { } )
BiggestMovers