Reputation: 24874
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?
Upvotes: 0
Views: 747
Reputation: 4360
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 require
s 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);
}
Upvotes: 1
Reputation: 804
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.
Upvotes: 0