A better way of handling _yield in components

I blogged about the problem of context when yield is called within a component here and it is also possibly more relevant in this gist.

The problem is basically that the context defaults to whatever the parentView is or whatever view the {{what-ever}} component is added to, unless you override the _yield method.

I have yet to come across a situation where the context makes sense in the parentView but I am sure there is one so my suggestion is to either make the context by default the component’s view or to have someway of toggling it.

What are others thoughts? I want to put together a PR for this as I don’t want to have lots of code with an overriden _yield method that might break down the line.

Yeah, I have been having this problem a bit creating a component that incorporates ember-table component…

This is an example of what I’ve been doing, but without ember table:

The problem with this using ember table is that with the ember-table structure goes roughly:

my-component → ember-table-component → ember-table-row → cell group view → cells … (etc)

And what I’ve been wanting to do is add something into each row by overriding the row and template and adding a component call into the template after the standard row stuff… the problem for me is, I want to specify an additional bit of template to be used on each row, but specified in my component that wraps the ember-table. I want to write something like this:

{{#my-component content=model}}
  {{name}} {{height}} {{weight}}
{{/my-component}}

Where the block content should actually be evaluated in the ember-table-row context. As it stands, I’m overriding _yield to eval with ‘view’ as the context in two places: on my-component, and on my custom ember-table-component.

The end result, though, is that I have to reference my values with some strange content.content.name or content.content.height method… it’s really ugly and probably beyond my understanding of how it all hooks up properly.

It’d be super sweet if when defining a component if I could somehow pass the passed in template “block” around … then I could just pass in on down the line until it gets to the right spot, and somehow “eval” it in the context it belongs in. That’d be absolutely super neat.

I wonder if I’m just doing things in a silly way.

1 Like

I would find it very useful to be able to bind to a component property from within its template (block). Currently overriding _yield but that is a bit brittle.

wycats mentioned the following in a related discussion:

Purely from an abstraction perspective, the code inside the block knows nothing about the view’s context. We may want to eventually provide ways for “block arguments” for the component to send information back in explicitly.

The way this should work (I think), is to have both a “template context/controller” and a “layout context/controller”. The yield helper would switch into the template context, while the component’s template (internally called the “layout”) would use the layout context/controller.

Source: