I am new to angularjs. I am trying angular 1.5 nested component. Can I bind parent component property in child component.
Ex:
<div ng-app='cbsApp' ng-controller='cbsCnt as ct'>
<cbs-cus-comp com-bind='ct.name'>
<child child-com-bind='cbsCusCompCntAs.name'></child>
</cbs-cus-comp>
</div>
I can get ct.name value in com-bind. But can't get cbsCusCompCntAs.name in child-com-bind. (cbsCusCompCntAs is cbs-cus-comp controller)
Working Plunker : https://plnkr.co/edit/axQwTn?p=preview
Thanks in advance.
In your first case you are referring directly to the controller scope via controllerAs
.
When using components in angular 1.5 you can get hold of your parent component via require
which will make parent's properties available after $onInit
as per Components Documentation:
Note that the required controllers will not be available during the instantiation of the controller, but they are guaranteed to be available just before the $onInit method is executed!
In your specific case you can update the child component to require the parent:
var child = {
require : {parentComp:'^cbsCusComp'},
template : 'Child : <b{{cbsCusChildCompCntAs.childComBind}}</b>',
controller : cbsCusChildCompCnt,
controllerAs: 'cbsCusChildCompCntAs'
};
and its controller to get the data you need (I used the same names as you just to see it work):
function cbsCusChildCompCnt(){
this.$onInit = function() {
this.childComBind = this.parentComp.name;
};
}
Updated plunker is here.
Wow... what a wonderful example... Took me a while to analyse it... so, I wrote my own (I think a bit more readable) version. I really do not know how to work with Plunker... so here's the code... Extract from my index.html file
<div ng-controller='appCtrl as ctrl'>
<parent bind-id='ctrl.name'>
<child bind-toid='parentCtrlAs.name'></child>
</parent>
</div>
The .js file
(function () {
'use strict';
var
parentComponent =
{
bindings :
{
bindId:'='
},
controller : parentCtrl,
controllerAs: 'parentCtrlAs',
restrict : 'A',
transclude : true,
templateUrl : 'parent.html',
};
var
childComponent =
{
controller : childCtrl,
controllerAs: 'childCtrlAs',
restrict : 'A',
require :
{
myParent :'^parent'
},
templateUrl : 'child.html',
};
angular
.module('app', [])
.controller('appCtrl' , appCtrl)
.component('parent' , parentComponent)
.component('child' , childComponent);
function appCtrl(){
this.name = 'Main..';
}
function childCtrl(){
this.$onInit = function() {
this.bindToid = this.myParent.name;
};
}
function parentCtrl(){
this.name = 'Parent Component';
}
})();
Hope it helps, Regards, Johnny
Although using the "require" parameter works, it creates a tightly bound relationship between the component acting as a child, which uses the "require" parameter, and the component acting as a parent, which consumes the child functionality.
A better solution is to use component communication as shown here.
Basically, you define a binding function in the child component definition, like so,
angular.module('app').component('componentName', {
templateUrl: 'my-template.html',
bindings: {
myFunction: '&'
},
controller: function() { // Do something here}
});
Then, in the parent markup you provide a function to call,
Parent HTML
<user-list select-user="$ctrl.selectUser(user)">
</user-list>
Finally, in the parent controller, provide an implementation of the selectUser function.
Here's a working Plunk.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With