Это может быть реализовано с помощью модуля pause
:
---
- hosts: server01
gather_facts: True
tasks:
- pause:
prompt: please enter the name for the target [{{ ansible_hostname }}]
register: prompt
- debug:
msg: "{{ prompt.user_input if prompt.user_input else ansible_hostname }}"
Я только что получил эту работу на своем собственном веб-сайте, поэтому я решил, что стоит разместить мое решение здесь.
<a [routerLink]="baseUrlGoesHere" fragment="nameOfYourAnchorGoesHere">Link Text!</a>
<a name="nameOfYourAnchorGoesHere"></a>
<div>They're trying to anchor to me!</div>
И затем в вашем компоненте убедитесь, что вы включили это:
import { ActivatedRoute } from '@angular/router';
constructor(private route: ActivatedRoute) {
this.route.fragment.subscribe ( f => {
const element = document.querySelector ( "#" + f )
if ( element ) element.scrollIntoView ( element )
});
}
Добавляя к ответ Калёяна , эта подписка привязана к маршрутизатору и будет жить до тех пор, пока страница не будет полностью обновлена. При подписке на события маршрутизатора в компоненте обязательно отмените подписку в ngOnDestroy:
import { OnDestroy } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { Subscription } from "rxjs/Rx";
class MyAppComponent implements OnDestroy {
private subscription: Subscription;
constructor(router: Router) {
this.subscription = router.events.subscribe(s => {
if (s instanceof NavigationEnd) {
const tree = router.parseUrl(router.url);
if (tree.fragment) {
const element = document.querySelector("#" + tree.fragment);
if (element) { element.scrollIntoView(element); }
}
}
});
}
public ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Простое решение, которое работает для страниц без каких-либо параметров запроса, совместимо с браузером назад / вперед, маршрутизатором и глубокой связью.
<a (click)="jumpToId('anchor1')">Go To Anchor 1</a>
ngOnInit() {
// If your page is dynamic
this.yourService.getWhatever()
.then(
data => {
this.componentData = data;
setTimeout(() => this.jumpToId( window.location.hash.substr(1) ), 100);
}
);
// If your page is static
// this.jumpToId( window.location.hash.substr(1) )
}
jumpToId( fragment ) {
// Use the browser to navigate
window.location.hash = fragment;
// But also scroll when routing / deep-linking to dynamic page
// or re-clicking same anchor
if (fragment) {
const element = document.querySelector('#' + fragment);
if (element) element.scrollIntoView();
}
}
Тайм-аут - это просто позволить странице загружать любую динамическую данные «защищены» с помощью * ngIf. Это также можно использовать для прокрутки до верхней части страницы при изменении маршрута - просто укажите основной якорный тег по умолчанию.
Решения выше не работали для меня ... Это сделало это:
Сначала подготовьте MyAppComponent
для автоматической прокрутки в 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 );
}
}
} );
}
}
}
Затем перейдите к my-app-route
, отправив 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 } );
}
}
После прочтения всех решений я искал компонент, и я нашел тот, который выполняет именно то, что задал первоначальный вопрос: прокрутка для привязки ссылок. https://www.npmjs.com/package/ng2-scroll-to
Когда вы его устанавливаете, вы используете синтаксис, например:
// app.awesome.component.ts
@Component({
...
template: `...
<a scrollTo href="#main-section">Scroll to main section</a>
<button scrollTo scrollTargetSelector="#test-section">Scroll to test section</a>
<button scrollTo scrollableElementSelector="#container" scrollYTarget="0">Go top</a>
<!-- Further content here -->
<div id="container">
<section id="main-section">Bla bla bla</section>
<section id="test-section">Bla bla bla</section>
<div>
...`,
})
export class AwesomeComponent {
}
Это сработало очень хорошо для меня.
Немного поздно, но вот ответ, который я нашел, работает:
<a [routerLink]="['/path']" fragment="test" (click)="onAnchorClick()">Anchor</a>
И в компоненте:
constructor( private route: ActivatedRoute, private router: Router ) {}
onAnchorClick ( ) {
this.route.fragment.subscribe ( f => {
const element = document.querySelector ( "#" + f )
if ( element ) element.scrollIntoView ( element )
});
}
Вышеприведенное не позволяет автоматически перейти к представлению если вы уже приземлились на страницу с якорем, поэтому я использовал решение выше в моем ngInit, чтобы он мог работать и с этим:
ngOnInit() {
this.router.events.subscribe(s => {
if (s instanceof NavigationEnd) {
const tree = this.router.parseUrl(this.router.url);
if (tree.fragment) {
const element = document.querySelector("#" + tree.fragment);
if (element) { element.scrollIntoView(element); }
}
}
});
}
Обязательно импортируйте Router, ActivatedRoute и NavigationEnd в начало вашего компонента, и все должно быть хорошо.
document.querySelector ( "#" + f )
дает мне ошибку, потому что она ожидает селектора, а не строки.
– Maurice
24 June 2018 в 14:02
element.scrollIntoView()
(без передачи element
в функцию). Чтобы сделать его гладким, используйте это: element.scrollIntoView({block: "end", behavior: "smooth"})
.
– Mr. B.
16 July 2018 в 10:22
Обновить
Теперь поддерживается
<a [routerLink]="['somepath']" fragment="Test">Jump to 'Test' anchor </a>
this._router.navigate( ['/somepath', id ], {fragment: 'test'});
Добавить код ниже вашего компонента для прокрутки
import {ActivatedRoute} from '@angular/router'; // <-- do not forget to import
private fragment: string;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
}
ngAfterViewInit(): void {
try {
document.querySelector('#' + this.fragment).scrollIntoView();
} catch (e) { }
}
Оригинал
Это известная проблема и отслеживается в https://github.com/angular/angular/issues/6595
123
в вопросе), предполагая, что маршрут маршрута ожидает такой параметр, как { path: 'users/:id', ....}
– Günter Zöchbauer
6 September 2016 в 19:30
Поскольку свойство фрагмента по-прежнему не обеспечивает привязку прокрутки, это обходное решение сделало для меня трюк:
<div [routerLink]="['somepath']" fragment="Test">
<a href="#Test">Jump to 'Test' anchor </a>
</div>
Я только что проверил очень полезный плагин, доступный в nmp - ngx-scroll-to , который отлично работает для меня. Однако он предназначен для Angular 4+, но, возможно, кто-то найдет этот ответ полезным.
Я пробовал большинство из этих решений, но столкнулся с проблемами, которые уходили и возвращались с другим фрагментом, и это не сработало, поэтому я сделал что-то немного другое, что работает на 100%, и избавляется от уродливого хэша в URL.
tl; dr вот лучший способ, чем то, что я видел до сих пор.
import { Component, OnInit, AfterViewChecked, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'app-hero',
templateUrl: './hero.component.html',
styleUrls: ['./hero.component.scss']
})
export class HeroComponent implements OnInit, AfterViewChecked, OnDestroy {
private fragment: string;
fragSub: Subscription;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.fragSub = this.route.fragment.subscribe( fragment => { this.fragment = fragment; })
}
ngAfterViewChecked(): void {
try {
document.querySelector('#' + this.fragment).scrollIntoView({behavior: 'smooth'});
window.location.hash = "";
} catch (e) { }
}
ngOnDestroy() {
this.fragSub.unsubscribe();
}
}
Несмотря на то, что ответ Гюнтера верен, он не охватывает «переход к» части метки привязки.
Поэтому дополнительно к:
<a [routerLink]="['somepath']" fragment="Test">Jump to 'Test' anchor </a>
this._router.navigate( ['/somepath', id ], {fragment: 'test'});
... в компоненте (родительском), где вам нужно поведение «перейти к», добавьте:
import { Router, NavigationEnd } from '@angular/router';
class MyAppComponent {
constructor(router: Router) {
router.events.subscribe(s => {
if (s instanceof NavigationEnd) {
const tree = router.parseUrl(router.url);
if (tree.fragment) {
const element = document.querySelector("#" + tree.fragment);
if (element) { element.scrollIntoView(true); }
}
}
});
}
}
Обратите внимание, что это обходной путь! Следуйте этой проблеме github для будущих обновлений. Кредиты на Виктор Савкин за предоставление решения!
"['../faq']"
в качестве значения, иначе он попытается перейти к / faq / faq / # anchor, insteaf of / faq / # anchor. Это правильный способ сделать это или есть более элегантный способ ссылаться на текущую страницу в routerlink? Кроме того, document.querySelector("#" + tree.fragment);
дает мне не допустимую ошибку выбора. Вы уверены, что это правильно?
– Maurice
24 June 2018 в 12:23
Вот еще один способ обхода проблемы с ответом на JavierFuentes:
<a [routerLink]="['self-route', id]" fragment="some-element" (click)="gotoHashtag('some-element')">Jump to Element</a>
в скрипте:
import {ActivatedRoute} from "@angular/router";
import {Subscription} from "rxjs/Subscription";
export class Links {
private scrollExecuted: boolean = false;
constructor(private route: ActivatedRoute) {}
ngAfterViewChecked() {
if (!this.scrollExecuted) {
let routeFragmentSubscription: Subscription;
routeFragmentSubscription = this.route.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();
}, 0);
}
}
});
}
}
gotoHashtag(fragment: string) {
const element = document.querySelector("#" + fragment);
if (element) element.scrollIntoView(element);
}
}
Это позволяет пользователю напрямую прокручивать элемент, если пользователь сразу приземляется страница с hashtag в url.
Но в этом случае я подписал маршрут Fragment в ngAfterViewChecked
, но ngAfterViewChecked()
вызывается непрерывно на каждый ngDoCheck
, и он не позволяет пользователю прокручивать назад, поэтому routeFragmentSubscription.unsubscribe
вызывается после тайм-аута в 0 миллисекундов после того, как представление прокручивается в элемент.
Кроме того, метод gotoHashtag
определен для прокрутки к элементу, когда пользователь специально нажимает на тег привязки.
Обновление:
Если url имеет querystrings, [routerLink]="['self-route', id]"
в якоре не будет сохранять повторы. Я попробовал следующее обходное решение для этого же:
<a (click)="gotoHashtag('some-element')">Jump to Element</a>
constructor( private route: ActivatedRoute,
private _router:Router) {
}
...
...
gotoHashtag(fragment: string) {
let url = '';
let urlWithSegments = this._router.url.split('#');
if(urlWithSegments.length){
url = urlWithSegments[0];
}
window.location.hash = fragment;
const element = document.querySelector("#" + fragment);
if (element) element.scrollIntoView(element);
}
Ни один из предыдущих ответов не работал для меня. В последнем попытке я попытался в своем шаблоне:
<a (click)="onClick()">From Here</a>
<div id='foobar'>To Here</div>
С этим в моем .ts:
onClick(){
let x = document.querySelector("#foobar");
if (x){
x.scrollIntoView();
}
}
И он работает как ожидается для внутренних ссылок. Это фактически не использует теги привязки, чтобы он вообще не касался URL.
element.scrollIntoView()
илиelement.scrollIntoView(true)
. Ваша версия не скомпилировалась для меня (возможно, из-за строгихNullChecks?). – David L. 15 January 2018 в 16:03