Today we are going to look at yielding values from a wrapping component to its wrapped context, then we will look at binding attributes to a component's element and finally we will look at how to place an HTML safe string in your templates.

We are starting with an new Ember project and let's generate a new component.

ember g component my-component

This component is going to be used as a block level component so we will want to leave our yield in place.

Let's add our new component to our application template:

{{#my-component}}
  Hello
{{/my-component}}

To reference properties inside of a wrapping component we use essentially the same syntax as we use for each blocks. We just add "as |someRef|".

{{#my-component as |someRef|}}
  Hello
{{/my-component}}

Then, in our component we can pass properties back out from our yield. We will pass it back out as a hash. So to access the foo property from inside our component block we just need to call {{someRef.foo}}

Inside Block Component:

{{yield (hash foo="BAR")}}

In parent template:

{{#my-component as |someRef|}}
  Hello {{someRef.foo}}
{{/my-component}}

Now, to add some attributes to our component's tag. If we want to add a class, we can do something as straight forward as adding the class when we call the component in our markup.

{{#my-component class='some-class' as |someRef|}}
  Hello {{someRef.foo}}
{{/my-component}}

We can also add a class in our component's template:

import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['foo']
});

We can also bind our class to a dynamic property using classNameBindings:

import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['foo'],
  classNameBindings: ['isOpen:open:closed'],
  isOpen: true
});

This will add a class of open to our component's element if isOpen is true and a class of closed if isOpen is false. If we just need the class for true values we can leave off the false value. We can also add non-class based properties to a component's tag by using attributeBindings. We can declare the property directly like this data property, or we can specify the component property first, then the tag's property name after a colon.

import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['foo'],
  classNameBindings: ['isOpen:open:closed'],
  isOpen: true,
  attributeBindings: ['data', 'dataFoo:data-foo'],
  data: 'just-some-data',
  dataFoo: 'candy'
});

With all of these changes, your generated element will look like this:

<div id="ember355" data="just-some-data" data-foo="candy" class="foo-bar ember-view foo open">
  Hello BAR
</div>

Let's look at one other template related tool you might need at some point as an ember developer. If you ever need to put a non-escaped string into you template you will need to tell the template it is safe. Here is an example. Say in our component we have a computed property that outputs a string containing some markup.

import Ember from 'ember';

export default Ember.Component.extend({
  someProperty: Ember.computed(function(){
    return "<strong>HEY YOU!!!</strong>";
  })
});
{{someProperty}}

If we put this in our template, it doesn't look quite like we expect, that is because Ember has our back and is keeping us safe. But we can tell Ember we know better by using triple curlys instead of double for our property. With triple curly braces, you are telling Ember that your string is safe and doesn't need escaping.

{{{someProperty}}}

You can also do this in JavaScript rather than the template by using Ember.String.htmlSafe:

export default Ember.Component.extend({
  someProperty: Ember.computed(function(){
    return Ember.String.htmlSafe("<strong>HEY YOU!!!</strong>");
  })
});

Then we can change back to the standard two curly braces in the template.

That is it for today, tomorrow we will look at some more resources to continue growing as an Ember Developer.