12

Hi i am trying to display simple components in angularjs where child needs to access parent name.And my code goes like this:

HTML file:

<html>
<head>
    <script type='text/javascript' src='angular.min-1.5.0.js'></script>
    <script type='text/javascript' src='app.js'></script>
</head>
<body ng-app="componentApp">
    <div ng-controller="helloCnt"> 
        <hello name="Parent"></hello>
        <hello1 name="Child"></hello1>  
        <label>List: <input name="namesInput" ng-model="names" ng-list=" | "   required></label>
    </div>
</body>
</html>

CODE:

app.component('hello', {
        transclude: true,
        template:'<p>Hello I am {{$ctrl.name}} and ctrl name is {{myName}}</p>',
        bindings: { name: '@' },
        controller: function($scope) {
                        $scope.myName = 'Alain';
                        alert(1);
        }
});

app.component('hello1', {
        require: {
            parent: 'hello'
        },
        template:'<p>Hello I am {{$ctrl.name}} && my parent is {{myNameFromParent}} </p>',
        bindings: { name: '@' },
        controller: function($scope) {
                        $scope.myNameFromParent=this.parent.myName;
                        alert(2);
        }
});

And it throws an error :

TypeError: Cannot read property 'myName' of undefined

I am not able to figure out what is wrong in the code and why it can't find the parent.Any inputs on the mistake I am making.Seems to be a small one I might have missed.

2
  • hello and hello1 are sibling scope, once check that! Commented Aug 9, 2016 at 12:48
  • I think something wrong with your component structure. A component should know nothing about the parent component. This is the best practice of component design. Commented Aug 9, 2016 at 12:56

2 Answers 2

6

Actually I got the answer after making following modification with the answer @gyc pointed:

JS CODE:

angular
    .module('componentApp', [])
    .controller('helloCtrl', function ($scope) {
        $scope.names = ['morpheus', 'neo', 'trinity'];
    })
    .component('hello', {
        transclude: true,
        template: '<p>Hello I am {{parentCtrl.name}} and my name is {{parentCtrl.myName}}</p><ng-transclude></ng-transclude>',
        controllerAs: 'parentCtrl',
        controller: function ($scope) {
            this.myName = 'Braid';
        },
        bindings: {
            name: '@'
        }
    })
    .component('hello1', {
        template: '<p>Hello I am {{$ctrl.name}} && my parent is {{myNameFromParent}}  </p>',
        controller: function ($scope) {
            this.$onInit = function () {
                $scope.myNameFromParent = this.parent.myName;
            };

        },
        bindings: {
            name: '@'
        },
        require: {
            parent: '^hello'
        }
    });

HTML:

<html>
<body ng-app="componentApp">
    <div ng-controller="helloCtrl">
        <hello name="Parent">
            <hello1 name="Child"></hello1>
        </hello>
        <label>List:
            <input name="namesInput" ng-model="names" ng-list=" | " required>
        </label>
    </div>
</body>
</html>

The common mistake I was doing it was not following the nested component format and not using transclude in my parent. The rest worked fine when I made these two changes and modified my subsequent code.

P.S - The ng-list included in HTML has nothing to do with components.That was for other purpose.

@gyc - thanks for the help.Your input helped.

@daan.desmedt - I was hoping for the solution in components not directives.

Sign up to request clarification or add additional context in comments.

Comments

5

To inherit with require, the components need to be nested:

<hello name="Parent"></hello>
<hello1 name="Child"></hello1>

instead do

<hello name="Parent">
    <hello1 name="Child"></hello1>
</hello>

Then you can require the parent like so:

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

3 Comments

hi.could you also explain what is the difference between using '^' and '^^' while inheriting parent in require property?
@AmbarBhatnagar with ^ you access a parent an local controller and ^^ just the parent.
@not quite got it.

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.