HTML links to routes in Angular app

1,186 views
Skip to first unread message

Thomas Baine

unread,
Aug 3, 2017, 9:44:48 PM8/3/17
to Angular and AngularJS discussion
How do I (re)format links within an external html file that target different routes in an Angular 4 app to "work" without reloading the app when clicked. The external html file, containing text and links, gets loaded into one view and contains links to the second view e.g.

<p>... blah blah blah.</p><p>Enter your survey data into <a href="/persons">the form</a> and click the 'Analyze' button</p><p>blah blah blah...</p>


How do I get links such as these, surrounded by text, to be re-purposed correctly (into, I guess, their routerLink equivalents) so that they behave like the routing links I have on my navbar and don't cause the app reloading when they are clicked?

Thanks, Tom

Joseph Ortega

unread,
Aug 4, 2017, 2:18:03 AM8/4/17
to ang...@googlegroups.com
Stop all this please I don't want no more of this crap

--
You received this message because you are subscribed to the Google Groups "Angular and AngularJS discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+unsubscribe@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Sander Elias

unread,
Aug 4, 2017, 5:55:05 AM8/4/17
to Angular and AngularJS discussion
Hi Thomas,

Here is a directive that takes anchors and rewrites them to use the router.

import { Directive, ElementRef, ContentChildren, ViewChildren } from '@angular/core';
import { Router, RouterLink  } from '@angular/router'


@Directive({ selector: '[rewriteAnchors]' })
export class rewriteAnchors {
   
   
@ViewChildren(RouterLink) AnchorsInView: QueryList<RouterLink>;
   
@ContentChildren( RouterLink) AnchorsInContent: QueryList<RouterLink>;
   
   
    constructor
(
     
private el: ElementRef,
     
private router: Router
   
) { }
   
    ngAfterViewInit
() {
     
const el = this.el.nativeElement;
     
//window.el = el;
      console
.log(this.AnchorsInView, this.AnchorsInContent, el)
     
if (el) {  
       
// this code only gets run in the browser, as other envs have (akaik) no nativeelement
       
const links = Array.from(el.querySelectorAll("a"))
         
.filter(l => !l.hasAttribute('ng-reflect-router-link'))
         
.map(l => (console.log(l),l))
         
.forEach(l => l.addEventListener('click', this.reroute(this)))
         
;
     
}
   
}
   
 
    reroute
(me) {
     
// use the closure to keep a reference to me(this)
     
return function reroute(ev) {
       
// might be confusing, but 'this' points to the element
       
// orignating the click.
        ev
.preventDefault();
       
const url = this.getAttribute("href")
        me
.router.navigateByUrl(url);
     
};
   
}
}



Is that what you are looking for?

Regards
Sander

Sander Elias

unread,
Aug 4, 2017, 6:27:36 AM8/4/17
to Angular and AngularJS discussion
Hi Joseph,


On Friday, August 4, 2017 at 8:18:03 AM UTC+2, Joseph Ortega wrote:
Stop all this please I don't want no more of this crap

Can you explain your meaning here? Is there something we can do to help? 

Regards
Sander 

Thomas Baine

unread,
Aug 6, 2017, 5:48:29 PM8/6/17
to Angular and AngularJS discussion

This is brilliant Sander, thank you.  I can't profess to understand exactly how it does what it does, but at my stage with Angular, it's a lot easier to learn from something complete that works compared to stumbling around with only an outcome in mind and no real idea of how to get there.

Cheers/Tom.
Message has been deleted

Shweta Sinha

unread,
Oct 26, 2018, 2:10:31 AM10/26/18
to Angular and AngularJS discussion
Hi Sander,

This is perfect and exactly what I am looking for..
I tried using the code and modify it to use but its not working for Angular 6. giving error "property does not exist on type" for has attribute and addEventlistner and 

class name not for QueryList,  

I am new to Angular and want to capture attribute from external file in angular to route. 

Thanks
Shweta

Sander Elias

unread,
Oct 26, 2018, 2:34:43 AM10/26/18
to Angular and AngularJS discussion
Hi Shweta,

Hmm, wrote it a while ago. Typescript got better in the meantime ;)
Updated the typings for you:

import { AfterViewInit, ContentChildren, Directive, ElementRef, QueryList, ViewChildren } from '@angular/core';
import { Router, RouterLink } from '@angular/router';

@Directive({ selector: '[rewriteAnchors]' })
export class RewriteAnchorDirective implements AfterViewInit {
  @ViewChildren(RouterLink)
  AnchorsInView: QueryList<RouterLink>;
  @ContentChildren(RouterLink)
  AnchorsInContent: QueryList<RouterLink>;

  constructor(private el: ElementRef, private router: Router) {}

  ngAfterViewInit() {
    const el = this.el.nativeElement;
    //window.el = el;
    console.log(this.AnchorsInView, this.AnchorsInContent, el);
    if (el) {
      // this code only gets run in the browser, as other envs have (akaik) no nativeelement
      const links = Array.from<HTMLAnchorElement>(el.querySelectorAll('a'))
        .filter(l => !l.hasAttribute('ng-reflect-router-link'))
        .map(l => (console.log(l), l))
        .forEach(l => l.addEventListener('click', this.reroute(this)));
    }
  }

  reroute(me) {
    // use the closure to keep a reference to me(this)
    return function reroute(ev) {
      // might be confusing, but 'this' points to the element
      // orignating the click.
      ev.preventDefault();
      const url = this.getAttribute('href');
      me.router.navigateByUrl(url);
    };
  }
}

This will fix the typing issues.
Regards
Sander

Shweta

unread,
Oct 26, 2018, 6:36:14 AM10/26/18
to Angular and AngularJS discussion
Hi Sander,
Thanks for the update!!
Error has gone and code works as expected.

I have one question what does 'ng-reflect-router-link' do in the code. Not able to understand that line.


regards

Shweta

Shweta

unread,
Oct 29, 2018, 7:40:55 AM10/29/18
to Angular and AngularJS discussion
Hi Sander,
I have changed reroute to fit my requirement but not sure why whole page is loading
I was trying to take external file attribute and compare with deferred list if attribute is there then load the page within component as it happens in angular.


ngOnInit() {
this._Faqservice.getFaqList();
}

reroute(me) {
// use the closure to keep a reference to me(this)
return function reroute(ev) {
// might be confusing, but 'this' points to the element
// orignating the click.
ev.preventDefault();

const routeattr = this.getAttribute('routeattr');

let routeid = this._Faqservice.getFaqList.id;

if (routeattr === routeid){
console.log("exists");
let routepageid = this._Faqservice.getFaqList.pageId
console.log(routepageid);
}


me.router.navigate(['/answer'], {relativeTo: me.activeRouter}, {
skipLocationChange: true,
});

}

route module file

const appRoutes: Routes = [
{ path: '', redirectTo: 'faqlist', pathMatch: 'full' },
{ path: 'faqlist', component: FaqlistComponent},
{ path: 'answer/:id', component: AnswerComponent }
];


service with method for deferred list

getFaqId(id: any) {
return this.getFaqList().then((obj) => obj.find(faqlist => faqlist.id === id));
}

getFaqList(){
var def = $.Deferred();
setTimeout(function(){
var obj = [
{id:'news', pageid:'1234'},
{id:'2', pageid:'4567' },
{id:'3', pageid:'97646709877' }
]
def.resolve(obj);
}, 100)
return def;
}


Thanks for your help, i can post the code on plunker if you want.

Regards
Shweta

Reply all
Reply to author
Forward
0 new messages