Why do we "require" ngModel in a directive vs inject it? - angularjs

Why do we "require" ngModel in a directive instead of in the directive injection arguments?
angular.module('customControl', ['ngSanitize']).
directive('contenteditable', ['$sce', function($sce) {
return {
restrict: 'A', // only activate on element attribute
require: '?ngModel',

Directives aren't injected. They are placed on elements which means that you need a specific instance in your custom directive.
requireing another directive on your own custom directive is how you tell Angular that to use your directive on an element, another directive is needed for things to work properly.

Related

Rename require ngModel in Angular directive

I have developed some directives and in them I use a certain pattern for naming attributes. All of the attributes are prefixed with "fs-" for example <div fs-attrtibute="value"></div>
Is it possible to use a custom name for the ngModel attribute and still retain the model controller functionality. For example <div fs-model="value" fsDirective></div>
myApp.directive('fsDirective', function() {
return {
require: 'fsModel',
link: function($scope, element, attrs, ngModel) {
ngModel.$setViewValue('StackOverflow');
};
}
};
});
As you've presented it here Angular would look for a controller on a directive named 'fsModel' and supply that to your link function's 'ngModel' argument. It might be possible to wrap ngModel in a custom 'pass-thru' directive, but that would introduce complexity for very small benefit.
We similarly use a 'namespace' for all of our local directives, but leave Angular's 'ng' space alone because it's clear and consistent.

AngularJS: How to create public API on directive to be called from controller?

I have an attribute directive and I'd like to expose an API on that directive to be called on the controller.
I followed the top answer from this question but this no longer seems to work anymore, or at least it doesn't work for me. Since it's been almost three years, how can I do this now?
In my "myDirective" directive I have:
return {
restrict: 'A',
scope: {
api: '='
},
link: function(scope, element){
scope.api = {
someFunction: function(){...}
}
...
}
In my markup I have:
<div myDirective api="b"></div>
And finally in my controller, I try to call:
$scope.b.someFunction() --> undefined is not an object
The way to do so, is to create a service that is used as an API for both the directive and the controller.
Inject the service into your directive controller to use it in the directive, and inject it into the controller.
All the API logic should be in the service, so calling the functions from either the directive or the controller will have the same result.

Angular: data not passing from controller to directive using isloated scope

The question title explain my problem i want to send data from a controller to directive so i can use the data in the directive controller or view.
Here is the controller code:
$scope.following = product.vendorId.isUserFollowing;
In the controller view:
<vas-follow following="{{following}}"></vas-follow>
following the property am trying to pass to the directive, the directive code:
.directive('vasFollow', vasFollow);
function vasFollow() {
var directive = {
restrict: "EA",
scope: {
following: '#'
},
link: link,
controller: vasFollowCtrl,
templateUrl: 'templates/directives/vasFollow.html',
};
return directive;
function link(scope, element, attrs) {
/* */
};
}
I tried first to use the following like so {{following}} in the directive view but it's not passing, also it is undefined in the directive controller.
I have read a lot of slimier issues but, i couldn't conclude why am having this problem.
Use ng-model for directive instead of your own replacement for it
Remove {{}} from assignment to share link to variable instead of just evaluated value
And please, use div or common DOM element instead of exact naming directive - it have side-effects in I.E.

AngularJS directive : require ngBind

I'm currently writing an attribute directive relying on the use of ngBind. I need the element to bear a ngBind attribute for the directive to work. I was thinking that a simple require: 'ngBind' would be enough, just like you'd do with ngModel. So here's what I did :
app.directive( 'myDirective', function() {
return {
restrict: 'A',
require: 'ngBind',
link: function(scope, element, attrs) { .. }
});
And here's how I use my directive:
<span my_directive="" ng_bind="valueToBeBound"></span>
But then I get this error, so I suppose it can't be done this way:
Error: error:ctreq
Missing Required Controller
Controller 'ngBind', required by directive 'myDirective', can't be found!
Is there any means to force the presence of ngBind ?
Thanks !
This is an expected behaviour. As defined in the AngularJS documentation for a directive's require option states that:
Require another directive and inject its controller as the fourth
argument to the linking function. The require takes a string name (or
array of strings) of the directive(s) to pass in. If an array is used,
the injected argument will be an array in corresponding order. If no
such directive can be found, or if the directive does not have a
controller, then an error is raised (unless no link function is
specified, in which case error checking is skipped).
Since the ngBind directive required by myDirective does not have a controller then an error is expected to be raised, unless you remove the link function in your myDirective directive then angular will simply skip the error checking.
There are two ways to achieve what you want.
Remove the link() function in your myDirective directive then add a controller function in that directive to add your component logic. The problem with this solution is that you can't attach DOM logic in your link() function.
The most ideal way to deal with the problem is to simply remove the require option and simply check the existence of the ngBind attribute in the element where your myDirective directive resides.
e.g.
app.directive( 'myDirective', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
if(angular.isUndefined(attrs.ngBind)) {
return;
}
// Your myDirective DOM LOGIC/MANIPULATION should be here
}
});
As explained well here: Angular NgModelController you need to provide the ngBind
<span ng-bind="ModelName"></span>

Is it possible to load a Directive in a Directive with AngularJS?

I'm trying to implement the http://logicbomb.github.io/ng-directives/drag-drop.html directive. I have another directive I'm trying to include it in...
angular.module('MyApp')
.directive('seconddirective', function ($rootScope, $lvlDraggable) {
return {
restrict: 'A',
but that doesn't work... so is this possible?
You may refer to this:
http://www.bennadel.com/blog/2471-Delegating-Nested-Directive-Behavior-To-Parent-Directive-In-AngularJS.htm
or this:
Nesting directives within directives

Resources