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.
Related
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>
I have some custom directive and I've bound ng-model and ng-change directives info this.
Example:
<custom-directive ng-model="users" ng-change="changed()">
</custom-directive>
directive after execute contains some inputs, textareas etc. I want to execute function bound into ng-change, changed() always when something is changed in this inputs, textareas.
Can I execute ng-change from directive controller or link?
Like this for example:
.directive('customDirective', function () {
return {
restrict: 'E',
replace: true,
require: 'ngModel',
templateUrl: 'src/template.html',
link: function (scope, elem, attrs, ngModel) {
executeNgChange();
}
};
})
You should be able to bind the function in ng-change in your directive using angular's Scope Function Expression Binding:
.directive('customDirective', function () {
return {
restrict: 'E',
replace: true,
require: 'ngModel',
scope: {
change: '&ngChange'
}
templateUrl: 'src/template.html',
link: function (scope, elem, attrs, ngModel) {
scope.change(); // or use ng-change="change()" in your directive template
}
};
})
I haven't tested this myself but hopefully it helps you.
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'
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.
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;
}
};