The @memberjunction/ng-link-directives package provides a set of Angular directives that transform text elements into different types of links based on MemberJunction entity field metadata. This makes it easy to display email addresses, URLs, and entity relationships as clickable links in your application.
mjEmailLink) - Converts fields with "email" extended type to mailto: linksmjWebLink) - Converts fields with "url" extended type to external linksmjFieldLink) - Creates navigable links to related entity recordslink-text class for consistent stylingnpm install @memberjunction/ng-link-directives
Import the LinkDirectivesModule in your Angular module:
import { NgModule } from '@angular/core';
import { LinkDirectivesModule } from '@memberjunction/ng-link-directives';
@NgModule({
imports: [
// other imports...
LinkDirectivesModule
],
})
export class YourModule { }
The email link directive converts text into a mailto: link when the field has an extended type of "email".
<span [mjEmailLink]="field">{{ field.Value }}</span>
// In your component
import { EntityField } from '@memberjunction/core';
export class YourComponent {
field: EntityField; // EntityField with ExtendedType = "email"
}
Note: The directive will log an error if the field's ExtendedType is not "email". There is a known issue where the error message incorrectly references "mjWebLink" instead of "mjEmailLink".
The web link directive converts text into an external URL link when the field has an extended type of "url".
<span [mjWebLink]="field">{{ field.Value }}</span>
// In your component
import { EntityField } from '@memberjunction/core';
export class YourComponent {
field: EntityField; // EntityField with ExtendedType = "url"
}
Note: The directive will log an error if the field's ExtendedType is not "url". Links open in a new tab by default.
The field link directive creates a link to another entity record when the field is a foreign key to another entity.
<!-- Basic usage -->
<span [mjFieldLink]="true" [record]="customerRecord" [fieldName]="'AssignedUserID'">
{{ customerRecord.Get('AssignedUserID') }}
</span>
<!-- With text replacement disabled -->
<span [mjFieldLink]="true" [record]="customerRecord" [fieldName]="'AssignedUserID'" [replaceText]="false">
{{ customerRecord.Get('AssignedUserID') }}
</span>
// In your component
import { BaseEntity } from '@memberjunction/core';
export class YourComponent {
customerRecord: BaseEntity; // Entity record containing the foreign key field
}
The directive:
/resource/record/{primaryKey}?Entity={EntityName} when clickedreplaceText=true)RelatedEntityNameFieldMap metadata for efficient name resolutionSelector: [mjEmailLink]
| Input | Type | Required | Description |
|---|---|---|---|
field |
EntityField |
Yes | The entity field object containing email data. Must have ExtendedType = "email" |
Selector: [mjWebLink]
| Input | Type | Required | Description |
|---|---|---|---|
field |
EntityField |
Yes | The entity field object containing URL data. Must have ExtendedType = "url" |
Selector: [mjFieldLink]
| Input | Type | Default | Required | Description |
|---|---|---|---|---|
mjFieldLink |
boolean |
- | Yes | Enable the directive (must be set to true) |
record |
BaseEntity |
- | Yes | The entity record object containing the field |
fieldName |
string |
- | Yes | The name of the field that contains the foreign key |
replaceText |
boolean |
true |
No | Whether to replace the field value with the related entity's name |
Events: The directive handles click events internally to navigate using Angular Router.
All directives extend the BaseLink abstract class, which provides a common CreateLink method:
protected CreateLink(
el: ElementRef,
field: EntityField,
renderer: Renderer2,
href: string,
newTab: boolean = false
): void
This method:
<a> element using Angular's Renderer2link-text CSS classtarget="_blank" for new tab behaviorThe EmailLink directive:
The WebLink directive:
The FieldLink directive provides the most complex functionality:
/resource/record/{primaryKey}?Entity={EntityName}RelatedEntityNameFieldMap for local field mappingGetEntityRecordName() API call if neededNote: Currently supports only single-value primary keys for foreign key relationships.
All generated links include the CSS class link-text for consistent styling across your application:
.link-text {
color: #0066cc;
text-decoration: underline;
cursor: pointer;
}
.link-text:hover {
color: #0052a3;
text-decoration: none;
}
.link-text:visited {
color: #551a8b;
}
Here's a complete example showing all three directives in action:
// component.ts
import { Component, OnInit } from '@angular/core';
import { BaseEntity, Metadata } from '@memberjunction/core';
@Component({
selector: 'app-contact-details',
template: `
<div class="contact-info">
<!-- Email link -->
<div>
Email: <span [mjEmailLink]="emailField">{{ contact.Get('Email') }}</span>
</div>
<!-- Web link -->
<div>
Website: <span [mjWebLink]="websiteField">{{ contact.Get('Website') }}</span>
</div>
<!-- Field link with name replacement -->
<div>
Account Manager:
<span [mjFieldLink]="true" [record]="contact" [fieldName]="'AccountManagerID'">
{{ contact.Get('AccountManagerID') }}
</span>
</div>
</div>
`
})
export class ContactDetailsComponent implements OnInit {
contact: BaseEntity;
get emailField() {
return this.contact.Fields.find(f => f.Name === 'Email');
}
get websiteField() {
return this.contact.Fields.find(f => f.Name === 'Website');
}
async ngOnInit() {
const md = new Metadata();
this.contact = await md.GetEntityObject('Contacts');
await this.contact.Load(123); // Load specific contact
}
}
This package uses the Angular CLI compiler (ngc) for building:
# Build the package
npm run build
# The compiled output will be in the ./dist directory
The package is configured with:
This package is designed to work seamlessly with the MemberJunction framework:
/resource/record/...)ISC
Runtime Dependencies:
Peer Dependencies:
Development Dependencies: