gpt4 book ai didi

Angular 2 从 ComponentInstruction 获取 URL

转载 作者:太空狗 更新时间:2023-10-29 18:27:04 24 4
gpt4 key购买 nike

我有一个缓存组件的自定义 router-outlet

代码是这样的:https://gist.github.com/waeljammal/467286d64f59f8340a93#file-persistentrouteroutlet-ts-L75

代码示例使用组件类型作为缓存键 - 但是,我需要通过 URL 缓存我的组件类型,以便我可以缓存同一组件的两个不同实例。

有什么方法可以根据ComponentInstruction获取URL吗?

最佳答案

所以我现在开始工作了。错误是我将 PersistenRouterOutlet 应用于顶级路由器。

考虑 urlPath:/space/settings/general

我的 App 组件中有一个 router-outlet,然后我有一个绑定(bind)到 space WorkspaceComponent urlPath.

WorkspaceComponent 然后托管它自己的 router-outlet 并定义一组子路由 - 从 URL,它监听 settings/general部分。

为了解决这个问题,我从我的 App 组件中删除了 persistent-router-outlet(替换为默认的 router-outlet

然后在 WorkspaceComponent 的模板中,我将默认的 router-outlet 替换为 persistent-router-outlet

最后但同样重要的是 - 将由子路由器(在 WorkspaceComponent 内)实例化的组件类型需要实现 CanReuse 接口(interface),并实现 routerCanReuse 方法:

routerCanReuse(next: ComponentInstruction, prev: ComponentInstruction) {
return next.urlPath === prev.urlPath;
}

PersistentRouterOutlet 的代码在这里:

"use strict";

import * as hookMod from 'angular2/src/router/lifecycle/lifecycle_annotations';
import * as routerMod from 'angular2/src/router/router';
import {isBlank, isPresent} from 'angular2/src/facade/lang';
import {StringMapWrapper} from 'angular2/src/facade/collection';
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
import {BaseException} from 'angular2/src/facade/exceptions';
import {
ElementRef, DynamicComponentLoader, Directive, Injector, provide, ComponentRef, Attribute
} from 'angular2/core';
import {
ComponentInstruction, CanReuse, OnReuse, CanDeactivate,
RouterOutlet, OnActivate, Router, RouteData, RouteParams, OnDeactivate
} from 'angular2/router';
import {hasLifecycleHook} from 'angular2/src/router/lifecycle/route_lifecycle_reflector';

/**
* Reference Cache Entry
*/
class RefCacheItem {
constructor(public componentRef: ComponentRef) {

}
}

/**
* Reference Cache
*/
class RefCache {
private cache: any = {};

public getRef(type: any) {
return this.cache[type];
}

public addRef(type: any, ref: RefCacheItem) {
this.cache[type] = ref;
}

public hasRef(type: any): boolean {
return !isBlank(this.cache[type]);
}
}

/**
* An outlet that persists the child views and re-uses their components.
*
* @author Wael Jammal
*/
@Directive({ selector: 'persistent-router-outlet' })
export class PersistentRouterOutlet extends RouterOutlet {
private currentInstruction: ComponentInstruction;
private currentElementRef;
private refCache: RefCache = new RefCache();
private resolveToTrue = PromiseWrapper.resolve(true);
private currentComponentRef: ComponentRef;

constructor(elementRef: ElementRef,
private loader: DynamicComponentLoader,
private parentRouter: Router,
@Attribute('name') nameAttr: string) {
super(elementRef, loader, parentRouter, nameAttr);

this.currentElementRef = elementRef;
}

/**
* Called by the Router to instantiate a new component during the commit phase of a navigation.
* This method in turn is responsible for calling the `routerOnActivate` hook of its child.
*/
public activate(nextInstruction: ComponentInstruction): Promise<any> {
let previousInstruction = this.currentInstruction;

this.currentInstruction = nextInstruction;

if (!this.refCache.hasRef(nextInstruction.urlPath)) {
let componentType = nextInstruction.componentType;
let childRouter = this.parentRouter.childRouter(componentType);

let providers = Injector.resolve([
provide(RouteData, { useValue: nextInstruction.routeData }),
provide(RouteParams, { useValue: new RouteParams(nextInstruction.params) }),
provide(routerMod.Router, { useValue: childRouter })
]);

return this.loader.loadNextToLocation(componentType, this.currentElementRef, providers)
.then((componentRef) => {
this.refCache.addRef(nextInstruction.urlPath, new RefCacheItem(componentRef));

this.currentComponentRef = componentRef;

if (hasLifecycleHook(hookMod.routerOnActivate, componentType)) {
return (<OnActivate>componentRef.instance)
.routerOnActivate(nextInstruction, previousInstruction);
}
});
}
else {
let ref = this.refCache.getRef(nextInstruction.urlPath);
ref.componentRef.location.nativeElement.hidden = false;

this.currentComponentRef = ref.componentRef;

return PromiseWrapper.resolve(
hasLifecycleHook(hookMod.routerOnReuse, this.currentInstruction.componentType) ?
(<OnReuse>ref.componentRef.instance).routerOnReuse(nextInstruction, previousInstruction) : true
);
}
}

/**
* Called by the Router during the commit phase of a navigation when an outlet
* reuses a component between different routes.
* This method in turn is responsible for calling the `routerOnReuse` hook of its child.
*/
public reuse(nextInstruction: ComponentInstruction): Promise<any> {
let previousInstruction = this.currentInstruction;
this.currentInstruction = nextInstruction;

if (isBlank(this.currentComponentRef)) {
throw new BaseException(`Cannot reuse an outlet that does not contain a component.`);
}

let ref = this.refCache.getRef(nextInstruction.urlPath);
let currentRef = ref ? ref.componentRef : null;

return PromiseWrapper.resolve(
hasLifecycleHook(hookMod.routerOnReuse, this.currentInstruction.componentType) ?
(<OnReuse>currentRef.instance).routerOnReuse(nextInstruction, previousInstruction) : true
);
}

/**
* Called by the Router when an outlet disposes of a component's contents.
* This method in turn is responsible for calling the `routerOnDeactivate` hook of its child.
*/
public deactivate(nextInstruction: ComponentInstruction): Promise<any> {
let next = this.resolveToTrue;
let ref = this.currentComponentRef;

if (isPresent(ref) && isPresent(this.currentInstruction) &&
hasLifecycleHook(hookMod.routerOnDeactivate, this.currentInstruction.componentType)) {
next = PromiseWrapper.resolve(
(<OnDeactivate>ref.instance)
.routerOnDeactivate(nextInstruction, this.currentInstruction));
}

return next.then(() => {
if (isPresent(ref)) {
ref.location.nativeElement.hidden = true;
}
});
}

/**
* Called by the Router during recognition phase of a navigation.
*
* If this resolves to `false`, the given navigation is cancelled.
*
* This method delegates to the child component's `routerCanDeactivate` hook if it exists,
* and otherwise resolves to true.
*/
public routerCanDeactivate(nextInstruction: ComponentInstruction): Promise<boolean> {
if (isBlank(this.currentInstruction)) {
return this.resolveToTrue;
}

let ref = this.currentComponentRef;

if (!ref) {
let foundRef = this.refCache.getRef(this.currentInstruction.urlPath);
ref = foundRef ? foundRef.componentRef : null;
}

if (hasLifecycleHook(hookMod.routerCanDeactivate, this.currentInstruction.componentType)) {
return PromiseWrapper.resolve(
(<CanDeactivate>ref.instance)
.routerCanDeactivate(nextInstruction, this.currentInstruction));
}

return this.resolveToTrue;
}

/**
* Called by the Router during recognition phase of a navigation.
*
* If the new child component has a different Type than the existing child component,
* this will resolve to `false`. You can't reuse an old component when the new component
* is of a different Type.
*
* Otherwise, this method delegates to the child component's `routerCanReuse` hook if it exists,
* or resolves to true if the hook is not present.
*/
public routerCanReuse(nextInstruction: ComponentInstruction): Promise<boolean> {
let result;

let ref = this.currentComponentRef;

if (!ref) {
let foundRef = this.refCache.getRef(nextInstruction.urlPath);
ref = foundRef ? foundRef.componentRef : null;
}

if (isBlank(this.currentInstruction) || !this.refCache.hasRef(nextInstruction.urlPath) || this.currentInstruction.componentType !== nextInstruction.componentType) {
result = false;
}
else if (hasLifecycleHook(hookMod.routerCanReuse, this.currentInstruction.componentType)) {
result = (<CanReuse>ref.instance)
.routerCanReuse(nextInstruction, this.currentInstruction);
}
else {
result = nextInstruction === this.currentInstruction ||
(isPresent(nextInstruction.params) && isPresent(this.currentInstruction.params) &&
StringMapWrapper.equals(nextInstruction.params, this.currentInstruction.params));
}

return PromiseWrapper.resolve(result);
}
}

关于Angular 2 从 ComponentInstruction 获取 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36096356/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com