在页面链接重新加载页面

时间:2016-06-25 15:40:02

标签: javascript html angular routing

我正在构建我的第一个Angular 2应用程序,现在我已经有了很好的Webpack构建系统,路由,服务和组件。

我尝试在我的某个组件中添加常规页面链接([href^="#"]),只要我在主页(/)上,它就可以正常工作,但每当我在不同的网址上将整个应用重新加载到主页。

显然这是一个已知问题(https://github.com/angular/angular/issues/6595),但我现在需要这个工作,所以我希望有人可以教我如何。

我不确定它会有所帮助,但这是我的组件的TS和HTML:

import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router-deprecated';

@Component({
    selector: 'home',
    template: require('./home.component.html'),
    directives: [ROUTER_DIRECTIVES]
})
export class HomeComponent {

}

<section id="home" class="section section--full-height">

    <h2>Title of the home page</h2>

    <nav>
        <a [routerLink]="['Search']" class="button button--wide">Search</a>
        <a [routerLink]="['Search']">Quick try</a>
    </nav>

    <footer>
        <a href="#home-2" class="icon-down icon--below">Heres how it works</a>
    </footer>

</section>

<section id="home-2" class="section section--full-height">

    <h2>Lorem ipsum dolor</h2>

    <img src="http://placehold.it/200x300">

</section>

正如您所看到的那样,链接&#34;这里是如何运作的&#34; (或者在页面链接中的任何其他内容 - 我实际上不止这一个)只有当您在主页(/)上时才能工作(向下滚动到链接的元素)。如果在任何其他网址上,该链接将重新加载该应用。

4 个答案:

答案 0 :(得分:3)

如果您不想修改任何内容:PLUNKER DEMO

只需将此指令放入您的组件中,即可完成。

@Directive({
  selector: 'a[href^=#]',
  inputs: ['href'],
  host: {
    "(click)": "linkClicked($event)"
  }
})
export class InPageLinks {
  href: string;

  linkClicked(e){ // handles click event, only prevents the links with a # in the beginning

      e.preventDefault();
      this.scrollToID(this.href);
  }

  scrollToID(id){ // scrolls to the given id
    let target = document.querySelector(id);

    document.body.scrollTop = target.offsetTop;  
    // current scroll-target is body, you can take another input if you want
  }
}

答案 1 :(得分:3)

在当前版本的路由器中 - 版本3.0.0-alpha.8 - 有一种方法可以将哈希片段添加到链接中。然而,角度团队仍然需要做一些工作才能使其正常运行。

在你的锚元素上,添加一个带有哈希值的fragment属性。

如果要生成本地链接,请使用以下表示法:

<a [routerLink]="['./']" fragment="Test">Jump to 'Test' anchor </a>

如果你在该地点

www.example.org/Comp1/Comp2

之前,这会将URL更改为

www.example.org/Comp1/Comp2#Test

链接到另一个组件时也可以这样做:

<a [routerLink]="['Comp3']" fragment="Test">Jump to 'Test' anchor </a>

将带您到

www.example.org/Comp1/Comp2/Comp3#Test

然而...

在angular的实现中似乎仍然存在一个错误。虽然链接是在浏览器的地址栏中正确生成和更新的,但浏览器不会跳转到指定的哈希位置。只有这样做,当你将光标移动到地址栏并按Enter键时,这显然无济于事。

我再次评论@powerbuoy和@Günter-Zöchbauer引用的github帖子,让Angular团队在这个问题上有所了解。

答案 2 :(得分:2)

不幸的是,我也学会了在发布之前尝试开发一个带有angular2的真实应用程序的艰难方法,你应该尽可能远离当前的开发,特别是在路由器方面

路由器的第三次迭代目前是非常alpha的,我遇到了很多问题,我不得不恢复它的实现,因为你可能已经知道,因为API已经发生了很大的变化,所以很有用。 / p>

就你的问题而言,我实际上并没有发现任何路由器实际上正确地实现了哈希,我不得不用一个类似下面的滚动组件来解决这个问题:

@Directive({
  selector: '[scroll-to-target-on-event]'
})
export class ScrollToTargetOnEventDirective {

  @Input('scroll-to-target-on-event') configs:Array<{target:Element, event:string}>;

  constructor(private _element:ElementRef) {
  }

  ngOnInit() {

    for (let config of this.configs) {
      this._element.nativeElement.addEventListener(config.event, () => {
          // Get the position of the target relative to the entire page. getBoundingClientRect is relative to the
          // viewport so to get relative to the entire page we subtract the body (as we're looking to use scrollpos)
          var targetYPos = config.target.getBoundingClientRect().top - document.body.getBoundingClientRect().top;

          // If the target position is below the bottom of the viewport then scroll to it. (This should actually
          // check above as well, haven't implemented it though)
          if (targetYPos > (document.documentElement.scrollTop || document.body.scrollTop) + (document.documentElement.clientHeight|| window.innerHeight)) {
            window.scrollTo(0, config.target.getBoundingClientRect().top - document.body.getBoundingClientRect().top);
          }
      });
    }
  }
}

然后,您可以将此指令添加到给定页面上的元素。

<a href="" [scroll-to-target-on-event]="[{target: '#id-of-target-element', event:'click'}]">Link</a>

我希望这可以帮助您暂时解决问题!

答案 3 :(得分:0)

https://github.com/angular/angular/issues/6595最近已修复,将包含在下一个版本中(可能是今天)