1
votes

I'm using angular 1.5 components in my application and here is my structure:

<body ng-app ng-controller="appController as app">
    <div ui-view="home">
        <home-component>
            {{ app.user }}
        </home-component>
    </div>
</body> 

Basically, I am using the ui-router for nested views together with Angular components.

I know that, using the controller as syntax, you can access the parent controller, however for some reason I cannot. Nothing is being displayed for {{ app.user }}

Now I have read, the the scope of a component is isolated, but I thought that simply means that parent components can't access child components.

If it is fully isolated, how would I go about accessing global data in parent controller?

Thank You!

3

3 Answers

1
votes

You can use requires to create a reference to it in the child component.

This syntax will basically everywhere to find it:

require: {
      app: '^homeComponent'
    }

Or this syntax will just look up one for the component as a parent:

require: {
      app: '^^homeComponent'
    }

Then in the child component you can reference the homeComponent via the app property.

You can also make the reference optional by prefacing it with a ? like:

  app: '?^^homeComponent'
1
votes

Use the require property to access a parent controller and map a binding to the controller of the child component:

app.component("homeComponent", {
  require: {main: "^ngController"},
  template: 
    `<fieldset>
      <h3>home-component</h3>
      <p> $ctrl.main.user = {{$ctrl.main.user}}</p>
    </fieldSet>`
})

The above example binds to the controller of the ng-controller directive.

From the Docs:

Intercomponent Communication

Directives can require the controllers of other directives to enable communication between each other. This can be achieved in a component by providing an object mapping for the require property. The object keys specify the property names under which the required controllers (object values) will be bound to the requiring component's controller.

— AngularJS Developer Guide - Components (Intercomponent Communication)

The DEMO

angular.module("app",[])
.component("homeComponent", {
  require: {main: "^ngController"},
  template: 
    `<fieldset>
      <h3>home-component</h3>
      <p> $ctrl.main.user = {{$ctrl.main.user}}</p>
    </fieldSet>`
})
.controller("appController", function() {
  var main = this;
  main.user = "someUser";
})
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app" ng-controller="appController as main">
      <h2>Main App</h2>
      <input ng-model="main.user" />
      <br><br>
      <home-component>
      </home-component>
  </body> 
0
votes

If a directive is isolated, it is best passing whatever values you need to use by parameters, else why making it isolated?

<home-component user="app.user"></home-component>

.directive('homeComponent', function() {
  return {
    scope: { user: '=' },
    ...
  }
})

Or you can transclude the content if it is not needed for use inside the child directive

<home-component>
    {{ app.user }}
</home-component>

.directive('homeComponent', function() {
  return {
    transclude: true,
    template: '<div><ng-transclude></ng-transclude></div>',
    ...
  }
})