Access all controllers of a directive - javascript

I have a directive which requires two controllers and has another controller specified with the controller property, TreeNodeController.
.directive('uiTreeNode', function () {
return {
require: ['^uiTreeNodes', '^uiTree'],
controller: 'TreeNodeController',
link: function (scope, element, attrs, controllers) { ... }
};
});
My question is how can I access the TreeNodeController from the link method?
When I log the controllers parameter, it is an array containing only the uiTreeNodes and uiTree controllers.

If you need access to the directive's controller, you have to require it too. Use the directive name (not the controller name) in the require array.
.directive('uiTreeNode', function () {
return {
require: ['^uiTreeNodes', '^uiTree', 'uiTreeNode'],
controller: 'TreeNodeController',
link: function (scope, element, attrs, controllers) {
var treeNodeCtrl = controllers[2];
}
};
});
If you're using controllerAs syntax, the controller is also on the scope:
.directive('uiTreeNode', function () {
return {
require: ['^uiTreeNodes', '^uiTree'],
controller: 'TreeNodeController',
controllerAs: 'view',
link: function (scope, element, attrs, controllers) {
var treeNodeCtrl = scope.view;
}
};

Related

how to pass multiple scope variables into custom directive in angularjs

I am trying to pass 2 scope variables from controller into a custom directive and having problem in accessing both of them.Model is same for the directive and controller.
Here is the code:
Html:
<myDirective data="var1" item="var2"></myDirective>
Controller:
$scope.var1="abc";
$scope.var2="xyz";
Directive:
app.directive('myDirective', function () {
return {
restrict: 'E', //E = element, A = attribute, C = class, M = comment
scope: {
var1: '='
var2:'='
},
templateUrl: 'myTemplate.html',
link: function ($scope, element, attrs) {
}
}
});
TemplateUrl: myTemplate.html
<div>{{var1}}</div> // This works
<div>{{var2}}</div> // This doesn't works
Any idea how can I use both?
Make these changes in your code
<popover data="var1" item="var2"></popover>
JS
app.directive('popover', function () {
return {
restrict: 'E', //E = element, A = attribute, C = class, M = comment
scope: {
data: '=',
item: '='
},
templateUrl: 'myTemplate.html',
link: function (scope, element, attrs) {
console.log(scope.data, scope.item);
}
}
});
Change your template to match the names declared in the DDO.
<myDirective var1="var1" var2="var2"></myDirective>
Avoid using data as an attribute name. That is a reserved prefix that is stripped during normalization. For more information on attribute normilization, see AngularJS Developer Guide - Directive Normilization.

Directives in object created during app lifetime doesn't work

I've created some basic directive. It works well if I use it with some objects in html file
<some-directive some-data="123"></some-directive>
But if I dynamically load this object to my webpage:
//getting html source as a string, then appending it to DOM:
elem.html("<some-directive some-data='123'></some-directive>");
The directive doesn't work (object is being added properly to DOM)
app.directive('someDirective', function (notes, parts) {
return {
restrict: 'AE',
scope: {
someData: '='
},
link: function (scope, elem, attrs) {
console.log("directive fired");
}
};
});
What can I do to make it work properly?
For dynamic directives, you have to use $compile service that compiles scope into template. Look at sample below, <some-directive-wrapper /> will add <some-directive /> element into itself and compile scope value
var app = angular.module('app', []);
app.directive('someDirective', function () {
return {
restrict: 'AE',
scope: {
someData: '='
},
template: '<h2>someDirective compiled, someData is {{someData}}</h2>',
link: function (scope, elem, attrs) {
console.log("directive fired");
}
};
});
app.directive('someDirectiveWrapper', function ($compile) {
return {
restrict: 'AE',
link: function (scope, elem, attrs) {
//get value from ajax maybe
//and set to scope
scope.data = 123;
//replace directive with another directive
elem.html('<h1>someDirectiveWrapper compiled </h1>\n<some-directive some-data="data"></some-directive>');
//compile scope value into template
$compile(elem.contents())(scope);
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<some-directive-wrapper></some-directive-wrapper>
</div>

Call method associated with directive in linking function

I have the following code:
.directive('ticketingChat', function() {
return {
restrict: 'E',
templateUrl: '/Reply/ReplyScreen',
scope: {},
controller: "TicketController",
link: function (scope, el, attr, ctrl) {
if (attr["ticketid"]) {
ctrl.loadTicketById(attr["ticketid"]);
}
}
}
})
I am trying to call the "loadTicketById" in my controller. However I can't seem to get an instance of the controller in the linking function whatever I do.
Other than that, the controller works in the directive.

Accessing parent formController in angular directive controller

In this question I have found how to access parent form within link in a directive. But I need it in my controller and access to form validation, so I implement this:
return {
restrict: 'A',
require: '?^form',
replace: true,
scope: {
someVariable: '='
},
link: function (scope, element, attrs, formCtrl) {
scope.formCtrl = formCtrl;
},
controller: function ($scope) {
$scope.someMethod = function () {
if ($scope.formCtrl.$valid) {
//Do something
}
}
}
};
It´s the correct way to do that? there's a better way?
EDIT: I need isolated scope and I´m actually using require: '?^form'

Angular: Directive: How to pass require form AND controller to link function

I have a directive called formNavHandler to handle dirty checking and navigation from page to page. formNavHandler relies on a controller called CoolFormCtrl and a form called coolForm. I want to pass both CoolFormCtrl and coolForm to the link function of formNavHandler
angular.module('cool').directive('formNavHandler', [
'$log', function($log) {
return {
restrict: 'A',
scope: {
disabled: '=coolFormDisabled'
},
controller: 'CoolFormCtrl',
require: 'form',
link: function(scope, elem, attrs, WhatsThis) {
$log.log(WhatsThis);
...
}
};
}
]);
used like so:
<form name="coolForm" form-nav-handler=true cool-form disabled="!CurrentUser.canUpdate">
...
</form>
My issue is that I cannot figure out how to pass both form and CoolFormCtrl through the link function.
If I comment out the require:'form' line then WhatsThis = CoolFormCtrl:
With the require:'form' line uncommented WhatsThis = coolForm
And when trying to pass a 5th parameter WhatsThis = coolForm and AndThis = undefined
controller: 'CoolFormCtrl',
require: 'form',
link: function(scope, elem, attrs, WhatsThis, AndThis) {
$log.log(WhatsThis);
$log.log(AndThis);
Is there any way to pass both a controller and required form to a directives link function?
Try:
angular.module('cool').directive('formNavHandler', [
'$log', function($log) {
return {
restrict: 'A',
scope: {
disabled: '=coolFormDisabled'
},
require: ['formNavHandler', 'form'],
controller: 'CoolFormCtrl',
link: function(scope, elem, attrs, WhatsThis) {
$log.log(WhatsThis);
...
}
};
}]);
WhatsThis will be an array of controllers.

Categories