I have the following directive I use to initialize the timeago plugin.
Directives.directive('timeago', function() {
return function(scope, element, attrs) {
$(element).attr('title', scope.post.utc_posted);
$(element).timeago();
}
});
How could I use/pass $log inside the function I'm returning?
You can just inject it the normal way. BTW element is already a jQuery variable and does not need $(element) - providing you're loading jQuery before Angular.
Directives.directive('timeago', function($log) {
return {
link: function(scope, element, attrs) {
element.attr('title', scope.post.utc_posted);
element.timeago();
}
}
});
Related
In angular directive init function i am declaring constant and utilizing the constant in html. I have multiple directives utilizing the same constant i want to keep the constants a reusable one.
In the below example i am using scope.sName and scope.sType in both test and test1 directive how can i have IT IN A COMMON PLACE AND REUSE IT.
app.directive('test', function() {
return {
restrict:'A',
scope: { someVal: '='}
link: function(scope, element, attrs) {
scope.sType = InvertoryConstant.serviceType;
scope.sName = InvertoryConstant.serviceName;
}
}});
app.directive('test1', function() {
return {
restrict:'A',
scope: { someVal: '='}
link: function(scope, element, attrs) {
scope.sType = InvertoryConstant.serviceType;
scope.sName = InvertoryConstant.serviceName;
}
}});
You can use the $provider.constant method in AngularJS for creating DRY constants:
angular.module('projectApp', [])
.constant('EXAMPLE_CONSTANT','exampleConstant')
You can inject EXAMPLE_CONSTANT into any of your modules, as a dependency
I have defined a custom click directive as below:
(function() {
'use strict';
angular.module('myApp.core')
.directive('customClick', customClick);
customClick.$inject = ['$rootScope'];
function customClick() {
return {
restrict: 'A',
/*scope: {
customClick: '&'
},*/
link: function(scope, element, attrs){
$(element).on('click', function(e) {
scope.$apply(function() {
console.log("Hello..customClick..");
scope.customClick();
});
});
}
};
}
})();
And I get the following error on this;
Error logged by WDPR Angular Error handler service {xx.."stacktrace":"TypeError: a.customClick is not a function","cause":"unknown cause"}(anonymous function)bowerComponents.js:5745
How can I resolve this? If I add scope with '&' I get demanding isolated scope. Hence how to resolve it?
If I remove - scope.customClick();, it does not show anything on second html for custom-click, it has impact on only 1 html, and its controller. I want to use it in multiple controller + html.
customClick is a function on the directive itself. It is not a function on the scope. That's why the error has occurred.
link is used to manipulate dom/add event handlers on elements, which you have rightly done with element.bind('click', function() {
Whenever click occurs, the function binded to click automatically gets invoked. There is no need of watch and the invoking statement.
Your link can just be
link: function(scope, element){
element.bind('click', function() {
console.log("Hello..customClick..");
});
}
As you have used camel case in naming the directive, exercise caution in its usage in template.
You can use it as <p custom-click>hi</p>
I would recommend you to avoid using jQuery in angular apps. Try following
angular.module('newEngagementUI.core')
.directive('customClick', customClick);
customClick.$inject = ['$rootScope'];
function customClick() {
return {
restrict: 'A',
scope: {
customClick: '&'
},
link: function(scope, element, attrs){
element.bind('click', function () {
scope.customClick();
})
}
};
}
In your template:
<div custom-click="clickFunction"></div>
And your template controller should be like:
angular.module('myApp', []).controller(['$scope', function ($scope) {
$scope.clickFunction = function () {
alert('function passed');
}
}])
Working fiddle here: https://jsfiddle.net/xSaber/sbqavcnb/1/
Given the following directive:
myApp.directive("test", function () {
return {
restrict: 'E',
scope: {
model: "="
},
template: "<div id='dialog_{{model.dialogId}}'></div>",
replace: true,
link: function (scope, element, attrs) {
alert($("dialog_" + scope.model.dialogId).length); <-- This is 0
}
}
});
I need to run a jQuery UI method on the div in the template, but I can't seem to get a reference to it from the DOM in my link function. Is there a way to run a function after the template has been added to the DOM?
You have element property.
You can do something like var div= element.find("div");
And if you want attach jquery plugin, just do $(div).jqueryPlugin();, you have to include jQuery, but if you don't angular provides jQuery Lite.
What I ended up doing was this:
link: function (scope, element, attrs) {
$timeout(function () {
alert($("#dialog_" + scope.model.dialogId).length);
}, 0);
}
I forgot to put the # in front of the selector, but it still only works if I use the timeout. Not sure why.
How can I access a directive's ngModelController from another directive?
The scenario
I'm creating a type ahead widget, which is composed of a typeAhead directive and autoCompletePopUp directive.
AutoCompletePopUp directive will interact with the typeAhead using typeAhead's controller.
But I don't know how to call typeAhead's $setViewValue from autoCompletePopUp when an item is selected.
Why not just add a function to the controller for typeAhead that calls $setViewValue on itself. In the context of typeAhead's controller you should have access to the scope. You can put the ngModelController for typeAhead on the scope if needed. Something like this:
angular.module("myModule").directive("typeAhead", function() {
return {
require: "ngModel",
controller: function($scope) {
this.setValue = function(value) {
$scope.ngModelController.$setViewValue(value);
};
},
link: function(scope, element, attributes, ngModelController) {
scope.ngModelController = ngModelController;
},
};
});
angular.module("myModule").directive("typeAhead", function() {
return {
require: "typeAhead",
link: function(scope, element, attributes, typeAheadController) {
scope.someAction = function(value) {
typeAheadController.setValue(value);
};
},
};
});
(protect against minification and move controllers into separate objects / files as desired; done inline here for convenience)
I'm writing a custom directive. I want the directive to add an ng-click attribute to the element
attrs.$set('ng-click','clicked()');
I have tried adding the ng-click directive in compile function, and pre and post link functions. The attribute is added but doesn't work. I appreciate any insights. Thanks!
.directive('myDir', function () {
return{
compile: function (tElement, tAttrs, transclude) {
//tAttrs.$set('ng-click','clicked()');
return {
pre: function (scope, element, attrs) {
//attrs.$set('ng-click','clicked()');
},
post: function (scope, element, attrs) {
//attrs.$set('ng-click','clicked()');
scope.clicked = function(){
console.log('clicked!!!');
};
}
};
}
};
});
You've added the attribute via jQuery so Angular doesn't know about it. The quick answer is to wrap the call in a scope.$apply:
scope.$apply(function() {
tAttrs.$set('ng-click','clicked()');
});
So Angular knows you changed it.
But for other approaches that might work more cleanly with Angular look at What is the best way to conditionally apply attributes in Angular?