How to avoid `require` and Access the controller of the parent component in transclusion

87 Views Asked by At

I'm trying to build a form component that receives an object as input and use the template defined into the object to ng-include the right template to render the form defined in the model.

The problem I have is the object might be defined in the above component. For example this:

   <somecomponent>
     <formx object="$ctrl.settings"></formx>
   </somecomponent>

Unfortunately, it doesn't seem to work. From what I read the transcluded block should be using the scope of the above controller. Is there a way to access the scope of the component somecomponent?

By the way, what I'm looking for is to do the same as:

 <div ng-controller="SomeController as ctrl">
   <formx object="ctrl.settings"></formx>
 </div>

But instead of using a plain controller I'd like to use a component without using an explicit require as the parent component might be different from time to time.

1

There are 1 best solutions below

1
On BEST ANSWER

With components the ng-include directive adds a child scope to the isolate scope. Transcluded components need to reference $parent:

<somecomponent settings="'ss'">
    ̶<̶f̶o̶r̶m̶x̶ ̶o̶b̶j̶e̶c̶t̶=̶"̶$̶c̶t̶r̶l̶.̶s̶e̶t̶t̶i̶n̶g̶s̶"̶>̶<̶/̶f̶o̶r̶m̶x̶>̶
    <formx object="$parent.$ctrl.settings"></formx>
</somecomponent>

The DEMO

angular.module("app",[])
.component("somecomponent",{
  transclude: true,
  bindings: {settings:"<"},
  template: `
    <fieldset>
       somecomponent scope-{{$id}}
     <ng-transclude>
     </ng-transclude>
    </fieldset>
  `
})
.component("formx",{
  bindings: {object:"<"},
  template: `
     <fieldset>
       formx scope-{{$id}}<br>
       object={{$ctrl.object}}
     </fieldset>
  `
})
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
   <somecomponent settings="'ss'">
     <formx object="$parent.$ctrl.settings"></formx>
   </somecomponent>
  </body>