Angular 1.5 Parent-Child Component Issue

716 Views Asked by At

I'm using Angular 1.5 Component router and having trouble getting a scope variable in the parent to be accessible in child components. I've created a plunker here that illustrates the problem. I've created a parent component with this view:

    <nav>
    <ul class="linkList">
        <li><a ng-class="{selected: $ctrl.isSelected('Applications')}" ng-link="['Applications', {search:$ctrl.search}]">Applications</a></li>
        <li><a ng-class="{selected: $ctrl.isSelected('Processes')}" ng-link="['Processes']">Processes</a></li>
        <li><a ng-class="{selected: $ctrl.isSelected('Tasks')}" ng-link="['Tasks']">Tasks</a></li>
        <li><a ng-class="{selected: $ctrl.isSelected('Resources')}" ng-link="['Resources']">Resources</a></li>
    </ul>
    <div class="filter">
        Filter: <input type="search" ng-model="$ctrl.search" />
    </div>
    <div class="clear"></div>
</nav>
<ng-outlet></ng-outlet>

Notice the "search" variable in the parent component view. I want this to be accessible to child components, but it's not working for me. I've seen examples that show child components being directly referenced in parent components like the following:

<application-grid search="$ctrl.search"></application-grid>

However, doesn't this defeat the purpose of the ng-outlet? I don't think I should have to manually pass parameters to child components like this right? What is the right way to do this?

2

There are 2 best solutions below

0
On

Just stumbled upon this - hoping you found the solution but if not here it is. You can get this to work easily using the require property.

Just add this to you child component set up and bingo:

require: {
   parent: '^app'
}

Then to access the parent scope object do $ctrl.parent.search.

Note you don't have to call it parent - it can be what ever name you like.

I've forked your plunkr - see it working http://plnkr.co/edit/epPg2xWY6IYJN2Fnvg61

3
On

You can access the route parameters through the $routerOnActivate lifecycle hook, which gets called automatically when the route transitions to that component. Here's the example from the Angular docs:

function HeroDetailComponent(heroService) {
    var $ctrl = this;

    this.$routerOnActivate = function(next, previous) {
        // Get the hero identified by the route parameter
        var id = next.params.id;
        return heroService.getHero(id).then(function(hero) {
            $ctrl.hero = hero;
        });
    };
...

Also, it's worth noting that components created with angular.module().component() always have isolate scopes - i.e., you can't access scope variables from the parent scope in them. They have to be explicitly passed down, either through the router or through the bindings.

For more information, you should take a look at the Component Router section of the Angular developer guide - the documentation for the new router is really sparse, but that guide does a good job of explaining how it all works.