Angular Component: how to specified value for output binding function defined in parent?

Problem

I wanted to use Angular 1.5's component to get benefit from its one-way binding: <hero-detail hero="ctrl.hero" save="ctrl.save(hero)"></hero-detail>. But, as Todd Motto points on his blog: Todd Motto's blog: One-way data-binding in Angular 1.5, it works properly only for primitives. So I had to bind primitives:

<hero-detail 
    name="ctrl.hero.name" 
    id="ctrl.hero.id"
    save="ctrl.save(ctrl.hero)"
  ></hero-detail>

And next in component, on $onInit hook, make hero object from primitives:

HeroDetailController.prototype.$onInit = function(){
  this.hero = {
    name: this.name,
    id: this.id
  } 
  console.log('OnInit called');
}

And call specified function when user clicks save. Weird part is, that if user changes hero's name inside component and clicks save, when function bound from parent is called, it does not have changes from hero-detail component. I made a plunker which shows my problem: Plunk which shows problem with children/parent output binding in Angular 1.5 - if you open Developer Console, click "Set name..." and then click save, you will see console.logs which will show you that from hero-detail it is Spawn2, but in parent context (where should be logic, like talking to $http service), it has still old value Spawn. Am I missing something? Code from Angular docs looks pretty like my code:

<button ng-click="$ctrl.onDelete({hero: $ctrl.hero})">Delete</button>

I have no clue what's going on. Thank you in advance for helping me to deal with this problem. P.S. I had some problem with Plunk versions, now everything is OK - in Developer Console in your browser you can see problems with updates

Problem courtesy of: Radek Anuszewski

Solution

To avoid confusion about the scope of variables (parent or child), prefix injected variables with $.

/* WAS
<hero-detail 
    name="ctrl.hero.name" 
    id="ctrl.hero.id"
    save="ctrl.save(ctrl.hero)"
 ></hero-detail>
 */

//SHOULD BE
<hero-detail 
    name="ctrl.hero.name" 
    id="ctrl.hero.id"
    save="ctrl.save($hero)"
></hero-detail>

Then in your code:

HeroDetailController.prototype.saveHero = function(hero) {
    console.log('Hero name from child: ' + hero.name);
    this.save({
      $hero: hero
    });
};

This way you can tell which variables of the expression are from the parent scope and which variables are from the directives scope.

Solution courtesy of: georgeawg

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.