Reputation: 3735
I have an Angular directive that searches user submitted text and replaces urls with anchor tags.
function findUrls($compile) {
var linkPatterns = new Array({
pattern: /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
template: ' <a class="absolute_link" href="$1" target="_blank">$1</a>'
},
{
pattern: /(^|[^\/])(www\.[\S]+(\b|$))/ig,
template: ' <a class="absolute_link" href="http://$2" ng-click="alert(\'hello\')" target="_blank">$2</a>'
},
{
pattern: /([a-z0-9._-]+@[a-z0-9._-]+\.[a-zA-Z0-9._-]+)/ig,
template: ' <a class="absolute_link" href="mailto:$1" ng-click="alert(\'hello\')" target="_blank">$1</a>'
},
{
pattern: /(^|[^a-z0-9@\\\/._-])([a-z0-9]{0,256}\.(com|net|org|edu)([a-z0-9\/?=\-_#]{0,256})?(\b|$))/ig,
template: ' <a class="absolute_link" href="http://$2" ng-click="alert(\'hello\')" target="_blank">$2</a>'
});
return {
restrict: 'AC',
link: function (scope, elem, attrs) {
if (attrs.ngBind) {
scope.$watch(attrs.ngBind, _.debounce(wrapUrls));
}
if (attrs.ngBindHtml) {
scope.$watch(attrs.ngBindHtml, _.debounce(wrapUrls));
}
function wrapUrls(text) {
var html = elem.html();
var newHtml = html;
linkPatterns.forEach((item) => {
newHtml = newHtml.replace(item.pattern, item.template);
});
if (html !== newHtml) {
elem.html(newHtml);
$compile(elem.contents())(scope);
}
}
}
};
}
When a user clicks one of those links I want to be able to capture that click and log some information about the object it belongs to. However the directive doesn't know what object these belong to so the code to log the click should be handled on the controller.
I want the directive to notify the controller that one of these elements has been clicked and the controller will log the object's properties but I have no idea where to begin.
Upvotes: 0
Views: 57
Reputation: 1795
You can pass controllers function to the directive and invoke it from the directive when the link is clicked
return {
restrict: 'AC',
scope: { // **** Add this *****
alert: '&'
}
link: function (scope, elem, attrs) {
if (attrs.ngBind) {
scope.$watch(attrs.ngBind, _.debounce(wrapUrls));
}
if (attrs.ngBindHtml) {
scope.$watch(attrs.ngBindHtml, _.debounce(wrapUrls));
}
function wrapUrls(text) {
var html = elem.html();
var newHtml = html;
linkPatterns.forEach((item) => {
newHtml = newHtml.replace(item.pattern, item.template);
});
if (html !== newHtml) {
elem.html(newHtml);
$compile(elem.contents())(scope);
}
}
}
<div DIRECTIVE_NAME alert="notify(msg)"></div>
//controllers notify function
Upvotes: 3