0

First of all, I'm using components.

I have this "parent" component:

(function() {
  'use strict';

  angular
    .module('parentModule', [])
    .component('parent', {
      templateUrl: 'parent.tpl.html',
      controller: ParentCtrl,
        transclude: true,
        bindings: {
            item: '='
        }
    });

  function ParentCtrl() {
    var vm = this;
    vm.item = {
      'id': 1,
      'name': 'test'
    };
  }
})();

And I'm simply trying to share the object item with another component, like this:

(function() {
  'use strict';

  angular
    .module('childModule', [])
    .component('child', {
      templateUrl: 'child.tpl.html',
      controller: ChildCtrl,
      require: {
        parent: '^item'
      }
    });

  function ChildCtrl() {
    console.log(this.parent)
    var vm = this;

  }
})();

View (Parent):

Parent Component:

<h1 ng-bind='$ctrl.item.name'></h1>
<child></child>

View (Child):

Child component:

Here I want to print the test that is in the parent component
<h2 ng-bind='$ctrl.item.name'></h2>

Actually I'm getting the following error:

Expression 'undefined' in attribute 'item' used with directive 'parent' is non-assignable!

Here's the DEMO to illustrate better the situation

Can you explain to me how I can make it work?

2 Answers 2

1

You need to remove the bindings from yor parent component. bindings binds to the component controller like scope binds to a directive's scope. You're not passing anything to <parent></parent> So you have to remove it.

Then your child component requires a parent component, not an item. So

  require: {
    parent: '^parent'
  }

Of course the child template should be modified to:

<h2 ng-bind='$ctrl.parent.item.name'></h2>

Finally, if from the child controller you want to log the item that is inside the parent, you will have to write:

  function ChildCtrl($timeout) {
    var vm = this;
    $timeout(function() {
      console.log(vm.parent.item);
    });
  }

I never need the timeout in my components, so there might be something obvious that I missed.

http://plnkr.co/edit/0DRlbedeXN1Z5ZL45Ysf?p=preview

EDIT:

Oh I forgot, you need to use the $onInit hook:

this.$onInit = function() {
  console.log(vm.parent.item);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thanks a lot. So there's no necessity for the use of transclude: true, right?
0

Your child should take the item as input via bindings.

(function() {
  'use strict';

  angular
    .module('childModule', [])
    .component('child', {
      templateUrl: 'child.tpl.html',
      controller: ChildCtrl,
       bindings: {
        item: '='
       }
    });

  function ChildCtrl() {
    console.log(this.parent)
    var vm = this;

  }
})();

So your parent template will look like

<h1 ng-bind='$ctrl.item.name'></h1>
<child item="$ctrl.item"></child>

The rest should work same.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.