带有片段的Angular 2路由,异步数据

时间:2018-01-07 21:43:17

标签: angular asynchronous angular2-routing observable timing

我正在构建一个包含许多部分和另外两个页面的主页的网站。每个部分都是自己的组件。底部,接触,应通过锚链接触。我已成功地在主页上锚定到联系人部分。路由到"联系"但是,从不同的页面来看,我遇到了时间问题。当我将SetTimeOut参数增加到2s而不是1s时,该函数正常工作。但是,这是一个hacky解决方案。

我知道在Angular中使用片段进行路由仍然存在问题。谁能告诉我最好的方法来解决这个问题?我相信当我从项目或新闻页面路由到主页#contact时,数据加载会降低找到锚点的能力。

我尝试了ng2-page-scroll,并跟踪了这个帖子:https://github.com/angular/angular/issues/6595并尝试了大多数提议的解决方案。没有什么允许我从不同页面导航到主页上的联系人部分,至少没有2s SetTimeOut。

这是我的家庭组件,其中包含联系人组件。

  ngAfterViewInit(){
  this._route.fragment
    .subscribe(
      (fragment: string) => {
        console.log('is there a fragment?');
        console.log(fragment);
        const element = document.querySelector("#" + fragment)
        if (element) {element.scrollIntoView(); console.log(element);}
        else { console.log('no element i guess '); }
        // if (fragment){
        //   this.scrollToAnchor(fragment, 1000);
        // }
      }
    );
  }

这是我的导航标记:

<li class="nav-li">
   <a
     [routerLink]="['/']"
     fragment="contact"
     class="nav-a"
     (click)="_globalService.toggleNav()">
     contact
   </a>
</li>

这是我的HomeComponent,其中包含联系部分:

<div class="homeWrap" id="container">
  <app-splash-graphic id="splash" name="splash"></app-splash-graphic>
  <app-about id="about" name="about"></app-about>
  <app-projects></app-projects>
  <app-press></app-press>
  <div id="contact" name="contact">
      <app-contact></app-contact>
  </div>
</div>

我真的很茫然!任何智慧都非常感激。

2 个答案:

答案 0 :(得分:1)

我不完全确定您的代码结构,但您可以使用Angular路由解析防护并编写您自己的解决方案,这将在导航到所需路由之前为您提供完全加载的页面。我认为这将解决您的计时问题。

https://angular.io/guide/router#resolve-pre-fetching-component-data

答案 1 :(得分:0)

我为类似情况创建了一条指令:

/**
 * directive that causes the browser to scroll and focus to the anchor from the latest activated route fragment
 * usage:
 * link with fragment: <a tabindex="0" [routerLink]="['/']" fragment="contact">
 * html in / route page:
 * <section appFocusFragment>
 *  <a id="contact">First focused content after load</a>
 */
import { Directive, AfterViewInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Directive({
  selector: '[appFocusFragment]'
})
export class FocusFragmentDirective implements AfterViewInit  {
  private fragment: string;
  constructor(private route: ActivatedRoute) {
    // be sure the navigation goes to the # fragment
    this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
  }

  ngAfterViewInit(): void {
    try {
      const anchor = document.querySelector<HTMLAnchorElement>('#' + this.fragment);
      anchor.focus();
      anchor.scrollIntoView();
    } catch (e) { }
  }
}