J'ai donc utilisé le post suivant pour comprendre comment ajouter un fragment à l'URL.
Routage Angular2 avec hachage à l'ancre de la page
Et le fragment est bien ajouté, mais la page ne se déplace pas vers l'ancre obtenue. J'ai essayé d'utiliser les attributs name
et id
sur la destination div
, mais ni l'un ni l'autre ne semblent fonctionner.
J'utilise Angular Version 2.0.0-rc.3 et la version de routeur 3.0.0-alpha.6.
Merci!
<a [routerLink]="[]" fragment="destination">Go TO DIV</a>
<div id='destination'>
<h2>Destination</h2>
</div>
Il y a suffisamment d'espace entre les 2 éléments pour indiquer si la page est réellement déplacée.
Et comme dit précédemment, l’url ajoute correctement #destination
à elle-même.
Une solution de contournement pourrait consister à écrire une fonction dans votre composant qui définisse location.hash sur l'id du div auquel vous souhaitez accéder.
<a (click)="goTo('destination')">Go TO DIV</a>
<div id='destination'>
<h2>Destination</h2>
</div>
Puis dans votre composant:
goTo(location: string): void {
window.location.hash = location;
}
Cela a fonctionné pour moi:
Tout d’abord, préparez MyAppComponent
pour le défilement automatique dans ngAfterViewChecked () ...
import { Component, OnInit, AfterViewChecked } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
@Component( {
[...]
} )
export class MyAppComponent implements OnInit, AfterViewChecked {
private scrollExecuted: boolean = false;
constructor( private activatedRoute: ActivatedRoute ) {}
ngAfterViewChecked() {
if ( !this.scrollExecuted ) {
let routeFragmentSubscription: Subscription;
// Automatic scroll
routeFragmentSubscription =
this.activatedRoute.fragment
.subscribe( fragment => {
if ( fragment ) {
let element = document.getElementById( fragment );
if ( element ) {
element.scrollIntoView();
this.scrollExecuted = true;
// Free resources
setTimeout(
() => {
console.log( 'routeFragmentSubscription unsubscribe' );
routeFragmentSubscription.unsubscribe();
}, 1000 );
}
}
} );
}
}
}
Ensuite, accédez à my-app-route
envoi de prodID
hashtag
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component( {
[...]
} )
export class MyOtherComponent {
constructor( private router: Router ) {}
gotoHashtag( prodID: string ) {
this.router.navigate( [ '/my-app-route' ], { fragment: prodID } );
}
}
Après avoir vu toutes les solutions ici, j'ai décidé de suivre une directive simple et petite. Voici ce que j'ai fini avec:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({ selector: '[appAnchorTo]' })
export class AnchorToDirective {
@Input() target: string;
constructor(el: ElementRef) { el.nativeElement.style.cursor = 'pointer'; }
@HostListener('click', ['$event'])
onClick() { document.querySelector(this.target).scrollIntoView(); }
}
L'idée était de créer quelque chose de flexible pouvant être attaché à n'importe quel élément de la page.
Usage:
<a appAnchorTo target="#my-link">My Insights</a>
<div appAnchorTo target="#my-other-link">My Customers</div>
Et n'oubliez pas de déclarer la directive sur l'un de vos modules:
@NgModule({
...,
declarations: [
...,
AnchorToDirective,
]
})
Cette solution de contournement devrait faire l'affaire
<div [routerLink]="[]" fragment="destination">
<a href="#destination">Go TO DIV</a>
</div>
Voici une solution très simple qui a fonctionné pour moi:
Dans le composant, ajoutez cette méthode:
navigateTo(location: string): void {
// location will be a valid CSS ID selector; i.e. it should be preceded with '#'
window.location.hash = location;
setTimeout(() => {
document.querySelector(location).parentElement.scrollIntoView();
});
}
Et dans la vue, la balise <a>
ressemblera à ceci:
<a (click)="navigateTo('#destination')">Destination</a>
Vous pouvez également utiliser ce plugin https://www.npmjs.com/package/ng2-page-scroll Il effectue un défilement animé vers une ancre donnée.
J'ai trouvé un plugin très utile disponible dans nmp - ngx-scroll-to , qui fonctionne très bien pour moi. Cependant, il est conçu pour Angular 4+, mais peut-être que quelqu'un trouvera cette réponse utile.