1

am trying to pass a value from a parent-component to his nested child-component in angular 1.5

The value can be updated from the parents, but child cannot edit it, just show it. So is a one-way binding '<' right ?

And i cannot pass the child component right in the parent component declaration, because the parent component would have other uses too.

The point is my parent-component have common data stored, but them children gonna use it in different ways.

And the parent-component gonna be used multiples times, with different children, thats why i cannot pass the children inside parent declaration. I need to bind the info, for auto updates purposes, when parents updates the data, must be reflected by the children

HTML

<parent-component ng-transclude>
  <child-component name="$ctrl.characters.arya"></child-component>
  <child-component name="$ctrl.characters.john"></child-component>
</parent-component>

JS

   // Parent Component declaration
// /////////////////////////
(function() {
  'use strict';
  angular
    .module('app')
    .component("parentComponent", {
      transclude: true,
      controller: "ParentComponentController",
      template: 
        '<div class="parent-c"></div>'
    });
 })();



// Parent Component Controller
// /////////////////////////
(function() {
  'use strict';
  angular
    .module('app')
    .controller('ParentComponentController', ParentComponentController);

  function ParentComponentController() {
    var $ctrl = this;
    $ctrl.characters = {};
    $ctrl.characters.arya = "Arya Stark";
    $ctrl.characters.john = "John Snow";
  }
})();




//CHILD Component declaration
// /////////////////////////
(function() {
  'use strict';
  angular
    .module('app')
    .component("childComponent", {
      bindings: {
        name: '<'
      },
      controller: "ChildComponentController",
      template: 
        '<div class="child-c"' +
          '<h3>Im a child Component</h3>' +
          '<p><strong>Name: </strong>{{$ctrl.name}}</p>' +
        '</div>'
    });
 })();



// CHILD Component Controller
// /////////////////////////
(function() {
  'use strict';
  angular
    .module('app')
    .controller('ChildComponentController', ChildComponentController);

  function ChildComponentController() {
    var $ctrl = this;
  }
})();

Check the WORKING SAMPLE on plunkr


The require attribute is for components communication, but i'm trying to use it with no success :(, need a piece of light here.

Héctor León
  • 2,210
  • 2
  • 23
  • 36
  • Do you want to pass a name as an attribute to the component (through bindings) or by inheritance from the parent (through require)? – gyc Aug 17 '16 at 12:09

2 Answers2

2

you have to use : <child-component name="$parent.$ctrl.characters.arya"></child-component>to pass a value from a parent-component to his nested child-component

Dan M. CISSOKHO
  • 1,070
  • 1
  • 12
  • 27
  • Hi ! thanks for your answer. This works, but seems too easy to be real, is there some bad performance or bad practice about using this ? – Héctor León Aug 17 '16 at 13:21
  • It's better to have self contained element . You could easily use them in another project. But generally if you need external informations,inject them or bind them. – Dan M. CISSOKHO Aug 17 '16 at 13:26
  • The point is my parent-component have common data stored, but them children gonna use them of different ways. And the parent-component gonna be used multiples times, with different children, thats why i cannot pass the children inside parent declaration. I need to bind the info, for auto updates purposes, when parents updates the data, must be reflected by the children. – Héctor León Aug 17 '16 at 13:32
1

There are different issues with your code:

  function ParentComponentController() {
    var $ctrl = this;
    $ctrl.characters = {};
    $ctrl.characters.arya = "Arya Stark";
    $ctrl.characters.john = "John Snow";
  }

You don't need to define a local variable for this since not changing context anywhere.

controller: "ParentComponentController",

Don't pass a string to this property, pass a reference:

controller: ParentComponentController,

Then if you want to pass name through the parent controller with require in the child component:

require: { parent: '^^parentComponent' },

Now that you have the parent controller bound to child you can use it with:

{{$ctrl.parent.characters.arya}}

in the template.

http://plnkr.co/edit/3PRgQSGdBEIDKuUSyDLY?p=preview

If you need to pass the name as an attribute to your child components, you have to put the child components inside the parent's template so you can call $ctrl.

http://plnkr.co/edit/1H7OlwbumkNuKKrbu4Vr?p=preview

gyc
  • 4,300
  • 5
  • 32
  • 54
  • Hi! Thanks for your reply. On plunkr i have everything in one file, but in local i have 3 files for each component: 1 component.js, 1 component.controller.js, 1 component.template.html thats why i defined local variable and use string instead of reference. There is a way to get the Name as an attribute, but outside of the parent template ? like store the name in a child component variable or something like that. – Héctor León Aug 17 '16 at 13:14