AngularJS: Access formController of a form placed inside transcluded directive from parent controller
Solution 1
Because you are using transclude, the directive will create a child transcluded scope. There is no easy path from the controller scope (003) to the directive's transcluded scope (005):
(The hard/not recommended path is to go via private property $$childHead
on the controller scope, find the isolate scope, then use $$nextSibling
to get to the transcluded scope.)
Update:
From insights from this answer, I think we can get the formController inside the directive, then use =
to get it to the parent.
scope: { show: '=', formCtrl: '=' },
...
link: function(scope, element) {
var input1 = element.find('input').eq(0);
scope.formCtrl = input1.controller('form');
}
HTML:
<div modal show="modal.show" form-ctrl="formCtrl">
Solution 2
Here is my solution: I create such method in parent controller :
$scope.saveForm = function(form) {
$scope.myForm = form;
};
Then I call it in transcluded content:
<my-directive>
<form name="myForm">
<div ng-init="saveForm(myForm)"></div>
</form>
</my-directive>
After creating directive instance i have form controller instance in parent scope.
Related videos on Youtube
MilMly
Updated on June 20, 2022Comments
-
MilMly about 2 years
I've created a simple "modal dialog" directive, which uses transclude. I would like to place a form () inside the "modal dialog" directive. I would expect that formController of a form placed inside the directive, is going to be accessible in parent controller's scope, however it isn't. Take a look at the following fiddle, please: http://jsfiddle.net/milmly/f2WMT/1/
Complete code:
<!DOCTYPE html> <html> <head> <title>AngJS test</title> <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/foundation/4.0.9/css/foundation.min.css"> <style> .reveal-modal { display: block; visibility: visible; } </style> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js"></script> <script type="text/javascript"> var app = angular.module('app', []); app.controller('appCtrl', function ($scope) { $scope.model = { id: 1, name: 'John' }; $scope.modal = { show: false }; }); app.directive('modal', function () { return { scope: { show: '=' }, transclude: true, replace: true, template: '<div class="reveal-modal small" ng-show="show"><div class="panel" ng-transclude></div></div>' } }); </script> </head> <body ng-app="app"> <div ng-controller="appCtrl"> <div class="panel"> Id: {{ model.id }}<br> Name: {{ model.name }}<br> Controller formController: {{ form }}<br> Directive formController: {{ myForm }}<br> </div> <form name="form" class="panel"> <input type="text" ng-model="model.name"> </form> <a ng-click="modal.show=!modal.show">toggle dialog</a> <div modal show="modal.show"> <form name="myForm"> <input type="text" ng-model="model.name"> </form> </div> </div> </body> </html>
So my question is how to access or is it possible to access directive's formController from parent controller?
Thank you for answers.
-Milan
-
Langdon about 11 yearsIs that the right fiddle? No reference to
$scope.myForm
anywhere. -
MilMly about 11 yearsThere's a {{ myForm }} in HTML, which is same as $scope.myForm, I guess.
-
MilMly about 11 yearsThere's also {{ form }}, which references a form inside controller but outside of directive. This one works as expected, but myForm does not get to parent scope - appCtrl's scope :-(
-
Langdon about 11 yearsI really think you linked the wrong fiddle. There's no
myForm
, there's noappCtrl
, and there's noformController
in that fiddle. -
MilMly about 11 yearsYes, you're right, I forgot to update fiddle, thank you for notice. I updated the post with complete source as well as correct fiddle link. Thank you again :-)
-
-
Langdon about 11 yearsWhat generated those beautiful graphics?
-
MilMly about 11 yearsPerfect! :) Thank you Mark. I forked your fiddle to make it more general, so it looks for the form element instead of the first input: jsfiddle.net/milmly/utnd6
-
Mark Rajcok about 11 years@Langdon, I have a tool that I wrote/am writing. I use GraphViz's dot to generate the pictures. I have a directive that figures out the scope properties, and some Python code to generate the dot files.
-
a paid nerd about 11 years@MarkRajcok I'd love to see this tool when your finished, or at least a sample
.dot
file where I could copy the styles from! :) -
Mark Rajcok about 11 years@apaidnerd, here's a sample .dot file. If you want to add a label, see stackoverflow.com/a/15707752/215945
-
Eugene Gluhotorenko about 9 yearsNo really actually. Angular supposes controllers to deal with only data model. But anyway it is the best hack i found.
-
Mark Rajcok over 8 years@apaidnerd, the tool is finished and on github: Peri$scope.
-
Steve about 8 yearsThis method works great when you cannot edit the directive, such as when using Angular UI Bootstrap directives. See my issue here which was resolved with your method: stackoverflow.com/questions/37727443/…