我已经实现了一个简单的LocationStrategy
,它会禁用其他股票策略使用的浏览器位置栏更改。我想创建几个较小的应用程序,这些应用程序将被插入任意网页,其中不得触摸浏览器位置,但需要某种导航。这与新战略相得益彰。现在唯一缺少的是back()
- 导航功能。显然我不能再调用window.back()
但我也没有通过读取角度源找到任何内部方法来调用。我想我可以直接调用LocationStrategy.back()
,但我仍然需要一些方法让路由器更新当前视图。是否有一些事件我可以触发或其他东西来存档视图更新?
这是我的位置策略的当前实现:
import { Injectable, Inject, Optional, platform } from 'angular2/core';
import { LocationStrategy, PlatformLocation, APP_BASE_HREF, } from 'angular2/router';
import { joinWithSlash, normalizeQueryParams } from 'angular2/src/router/location_strategy';
import { UrlChangeListener } from 'angular2/src/router/location/platform_location';
import { isPresent } from 'angular2/src/facade/lang';
@Injectable()
export class HiddenLocationStrategy extends LocationStrategy {
private _baseHref: string = '';
private pathHistory: string[] = [];
private poppedPathHistory: string[] = [];
constructor(private _platformLocation: PlatformLocation,
@Optional() @Inject(APP_BASE_HREF) _baseHref?: string) {
super();
if (isPresent(_baseHref)) {
this._baseHref = _baseHref;
}
}
onPopState(fn: UrlChangeListener): void {
}
getBaseHref(): string { return this._baseHref }
path(): string {
return this.pathHistory.length > 0 ? this.pathHistory[this.pathHistory.length - 1] : '';
}
prepareExternalUrl(internal: string): string {
var url = joinWithSlash(this._baseHref, internal);
return url;
}
pushState(state: any, title: string, path: string, queryParams: string) {
this.pathHistory.push(path);
}
replaceState(state: any, title: string, path: string, queryParams: string) {
}
forward(): void { this.pathHistory.push(this.poppedPathHistory.pop()); }
back(): void { this.poppedPathHistory.push(this.pathHistory.pop()); }
}
答案 0 :(得分:0)
我会尝试提供自定义PlatformLocation
https://github.com/angular/angular/blob/master/modules/angular2/src/platform/browser/location/platform_location.ts并调用其forward()
和back()
方法。
abstract onPopState(fn: UrlChangeListener): void;
abstract onHashChange(fn: UrlChangeListener): void;
似乎是路由器订阅的事件。
另见https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate是
答案 1 :(得分:0)
该解决方案涉及利用history.pushState
API,在pushState
方法中放置逻辑,以记录递增标识符(以及您想要的任何其他状态)和onPopState
方法中的逻辑评估弹出状态是后向导航还是前向导航,最后是通过包装几个PlatformLocation
的方法。
import { APP_BASE_HREF, LocationStrategy, PlatformLocation, Location, LocationChangeListener } from '@angular/common';
import { Inject, Injectable, Optional } from '@angular/core';
import { isPresent } from '@angular/common/src/facade/lang';
export interface HistoryState {
state: any;
title: string;
path: string;
}
@Injectable()
export class HiddenLocationStrategy extends LocationStrategy {
private baseHref: string = '';
private pathHistory: HistoryState[] = [];
private poppedPathHistory: HistoryState[] = [];
constructor(
private platformLocation: PlatformLocation,
@Optional() @Inject(APP_BASE_HREF) baseHref?: string
) {
super();
if (isPresent(baseHref)) {
this.baseHref = baseHref;
}
}
onPopState(fn: LocationChangeListener): void {
this.platformLocation.onPopState((ev: PopStateEvent) => {
let backward = this.pathHistory.find((item) => item.state.uid === ev.state.uid);
let forward = this.poppedPathHistory.find((item) => item.state.uid === ev.state.uid);
if (backward) {
this.navigateBack();
} else if (forward) {
this.navigateForward();
}
fn(ev);
});
//this.platformLocation.onHashChange(fn);
}
getBaseHref(): string {
return this.baseHref;
}
path(): string {
return this.pathHistory.length > 0
? this.pathHistory[this.pathHistory.length - 1].path
: '';
}
prepareExternalUrl(internal: string): string {
return Location.joinWithSlash(this.baseHref, internal);
}
pushState(state: any, title: string, path: string, queryParams: string) {
state = Object.assign({}, state, {
uid: (new Date()).valueOf()
});
this.pathHistory.push({
state: state,
title: title,
path: path
});
this.platformLocation.pushState(state, title, this.prepareExternalUrl(''));
}
replaceState(state: any, title: string, path: string, queryParams: string) {
this.platformLocation.replaceState(state, title, path);
}
forward(): void {
this.platformLocation.forward();
}
back(): void {
this.platformLocation.back();
}
private navigateForward() {
this.pathHistory.push(this.poppedPathHistory.pop());
}
private navigateBack() {
this.poppedPathHistory.push(this.pathHistory.pop());
}
}