I have a angular directive:
app.directive('myDirective', function()
{
return{
restrict: 'AE',
scope: {
myCustomer: "&"
},
require: 'ngModel',
link: function(scope, element, attr, ngModel){
var oldVal;
function fromUser(value){
scope.myCustomer()(value, oldVal);
oldVal = value;
return value;
}
function toUser(value){
return value;
}
ngModel.$parsers.push(fromUser);
ngModel.$formatters.push(toUser);
}
}
}
At the moment I invoke this director by using attribute name and bind it to a function:
<input type="text" my-directive="showInput" ng-model="user.name">
It works fine but what I want is to use element name, something like this:
<my-directive>
The problem is I don't know how to bind to a function as I do with the attributes.
You will need to set 'restrict' to 'E' in your directive definition something like:
bindToController: true,
controller: 'YourController',
controllerAs: 'vm',
restrict: 'E', //<----this is what you want
templateUrl: 'template.html'
You have to pass restrict: 'E' in directive options
angular.module("image-management")
.directive('myDirective', ($modal) => {
return {
restrict: 'E',
scope:{
showInput: '&'
},
template: '',
link: function(){}
})
<my-directive showInput="showInput" ></my-directive>
<my-directive some-function="someFunction"></my-directive>
Then in your directive link function, it is accesible through attr
link: function(scope, element, attr, ngModel){
// Your logic...
attr.someFunction();
}
As #sumair answered, you can do:
<my-directive showInput="showInput" ></my-directive>
But, if you really want to use only
<my-directive>
AND your directive does not require to have an isolated scope, you can just leave the scope property of the directive definition and reference your showInput function directly from inherited scope like so:
app.directive('myDirective', function()
{
return{
restrict: 'AE',
/*scope: { ////// remove this part //////
myCustomer: "&"
},*/
require: 'ngModel',
link: function(scope, element, attr, ngModel){
var oldVal;
function fromUser(value){
scope.showInput()(value, oldVal);
oldVal = value;
return value;
}
function toUser(value){
return value;
}
ngModel.$parsers.push(fromUser);
ngModel.$formatters.push(toUser);
}
}
}
Related
I am creating an email directive as below,
angular.module('app')
.directive('email', function () {
return {
restrict: 'EA',
transclude: true,
template: '{{email}}',
link: function (scope, element, attrs, ctrl, transclude) {
transclude(scope, function (clone) {
scope.email = clone.text();
});
}
};
});
I am using it in the HTML as below,
<email>{{emailId}}</email>
However, I am unable to pass the interpolated value of emailId inside the directive. The output of the directive ends up as,
{{emailId}}
How do we pass the actual interpolated value inside the directive?
Plnkr - http://plnkr.co/edit/AeBfp3VayKihygelKr9C?p=preview
To pass a variable to directive scope, simply use an attribute:
angular.module('app')
.directive('email', function () {
return {
restrict: 'EA',
̶t̶r̶a̶n̶s̶c̶l̶u̶d̶e̶:̶ ̶t̶r̶u̶e̶,̶
template: '{{email}}',
link: function (scope, element, attrs, ctrl, transclude) {
//transclude(scope, function (clone) {
// scope.email = clone.text();
//});
scope.email = scope.$eval(attrs.addr);
//OR
scope.$watch(attrs.addr, function(value) {
scope.email = value;
});
}
};
});
Usage:
<̶e̶m̶a̶i̶l̶>̶{̶{̶e̶m̶a̶i̶l̶I̶d̶}̶}̶<̶/̶e̶m̶a̶i̶l̶>̶
<email addr="emailId"></email>
There is no need to use transclusion to evaluate an Angular Expression.
For more information, see
AngularJS scope.$eval API Reference
AngularJS scope.$watch API Reference
You Just have to add Only on directive template ng-transclude on your element
here is the code
angular.module('app')
.directive('email', function () {
return {
restrict: 'EA',
transclude: true,
template: '<a href="{{email}}" ng-transclude>{{email}}</a>',
link: function (scope, element, attrs, ctrl, transclude) {
}
};
});
here is the link
Plunker http://next.plnkr.co/edit/SY3ih9NwAqz7ZhZg?open=lib%2Fscript.js&preview
I have a custom directive:
<custom-directive style='height: {{window.innerHeight + "px"}}'></custom-directive>
myApp.directive('customDirective', function(){
return {
restrict: 'E',
templateUrl: '/views/controls/customTemplate.html'
};
});
So, the expression style='height: {{window.innerWidth + "px"}}' doesn't work. App just ignores it. How to make it work?
Write a link function in directive where you will get directive element as and argument use that to change the css of the element.
Like if you want to change the color of the directive text do like this -
link: function(scope, elem, attr) {
elem.css('color','red');
}
Diective
myApp.directive('customDirective', function(){
return {
restrict: 'E',
templateUrl: '/views/controls/customTemplate.html',
link: function(scope, elem, attr) {
elem.css('color','red');
}
};
});
What I want to do is to create an element directive, that can have bindable attributes and can work with static values.
Ex. I have a directive myTag which should support enablel/disable of some features... I want this to work like
<my-tag enable_f1="true" enable_f2="true" />
or like
<my-tag enable_f1="{{mc.someVal1}}" enable_f2="{{mc.someVal2}}" />
Now how can I write link method, to support binding to the attributes as well as static values?
angular.module('TestModule',[])
.directive('myTag',function() {
return {
restrict: 'E',
templateUrl: '<div></div>',
link: function (scope, element, attrs){
//I can get attrs.enable_f1, attrs.enable_f2, but what if it is bound to model?
}
}
});
You can have an isolated scope that gets these values:
HTML:
<my-tag enable-f1="mc.someVal1" enable-f2="mc.someVal2"></my-tag>
<my-tag enable-f1="true" enable-f2="false"></my-tag>
Directive:
myApp.directive('myTag',function() {
return {
restrict: 'E',
template: '<div></div>',
scope: {
enableF1: '=',
enableF2: '='
},
link: function (scope, element, attrs){
console.log(scope.enableF1);
console.log(scope.enableF2);
}
}
});
Fiddle
I am creating an angular directive and I want the user to specify a 'type' of the directive.
For example:
<my-directive type-a></my-directive>
or
<my-directive type-b></my-directive>
or
<my-directive type-c></my-directive>
I know I can do:
<my-directive type="a"></my-directive>
and then require the type attribute but then I'm doing string matching. Is there anyway to do this by requiring one of 'type-a', 'type-b', or 'type-c' to be present?
Without much background info, I came up with this solution.
JSFIDDLE
So basically myDirective has a controller which is shared by type directives (type-a, type-b.. and so on). The type directive sets the type on the scope of myDirective.
myApp.directive('myDirective', function() {
return {
restrict: 'E',
controller: function($scope) {
$scope.type = '';
this.setType = function(type){
if($scope.type === '') $scope.type = type;
else throw 'type can be only defined once. Current type is '+$scope.type
}
},
link: function(scope, elem, attrs) {
console.log(scope.type);
}
}
});
myApp.directive('typeA', function() {
return {
restrict: 'A',
require: '^myDirective',
link: function(scope, elem, attrs, ctrl) {
ctrl.setType('typeA');
}
}
});
myApp.directive('typeB', function() {
return {
restrict: 'A',
require: '^myDirective',
link: function(scope, elem, attrs, ctrl) {
ctrl.setType('typeB');
}
}
});
I think you can do <div data-my-directive="a"></div> which is a lot safer for cross-browser and w3c. Then the directive would be something like:
.directive('myDirective', function() {
return {
restrict: 'A',
scope: {
type: '='
},
link: function(scope,element,attrs){
}
};
});
The following directive:
var app = angular.module('demo', []);
app.directive('myDirective', function() {
return {
restrict: 'E',
template: '<h1>Foo bar</h1>'
};
});
With the following usage:
<my:directive foo="bar"></my:directive>
Renders the following HTML:
<my:directive foo="bar"><h1>Foo bar</h1></my:directive>
Since I want to replace my directive with the provided template I set replace:true. This produces the following HTML:
<h1 foo="bar">Foo bar</h1>
Note that Angular copies my directive's attributes to the template elements (the foo="bar"). How can I prevent this behaviour?
You can manually remove the attributes in the link function of the directive:
.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<h1>Foo bar</h1>',
link: function(scope, elm, attrs){
elm.removeAttr('foo');
}
};
});
Here's a fiddle with this directive working in your situation.
EDIT: You can extend this to remove all attributes dynamically with a simple loop:
.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<h1>Foo bar</h1>',
link: function(scope, elm, attrs){
for(var attr in attrs.$attr){
elm.removeAttr(attr);
}
}
};
});