lex*_*ith 9 angular2-routing angular
我有一个简单的TopbarComponent,它基本上在我的视图顶部添加了一个bootstrapish导航栏.
由于90%的模板都应该包含此指令,我想通过我的处理它app.component看起来像这样:
import ...;
@Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
directives: [ROUTER_DIRECTIVES, TopbarComponent, ...],
providers: [ROUTER_PROVIDERS, ...]
})
@RouteConfig([
{
path: '/login',
name: 'Login',
component: LoginComponent
},
{
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
useAsDefault: true
}
])
Run Code Online (Sandbox Code Playgroud)
其模板看起来像这样:
<my-topbar></my-topbar>
<div class="container-fluid">
<div class="row">
<router-outlet></router-outlet>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
现在我想使用ngIf(或除了用css隐藏它之外的任何其他方式)来隐藏几条路线上的顶杆,/login例如.我尝试了几种方法在我的使用@CanAcitvate()或实现(以及从我的尝试),但没有任何影响(甚至有问题甚至让功能开火).我得到的最接近的是直接使用我喜欢的:OnActivateLoginComponentAppComponentRouterAppComponent
export class AppComponent implements OnInit{
showTopbar:boolean;
constructor(private _router:Router) {}
ngOnInit():any {
this.showTopbar = this._router.lastNavigationAttempt != '/login';
}
}
Run Code Online (Sandbox Code Playgroud)
并在我的app.component.htmli中将指令更改为<my-topbar *ngIf="showTopbar"></my-topbar>
但这只适用于我的应用程序的初始加载,因为ngOnInit每次状态更改都不会触发原因.有没有类似的方法我可以使用(并且找不到)或者我在这里走向错误的方向?
目前,PierreDuc的答案对我不起作用,但我尝试了类似的方法,使用location.path()如下:
constructor(private _location:Location) {}
private get _hideTopbar() : boolean {
switch(this._location.path()){
case '/register':
case '/login':
return true;
default:
return false;
}
};
Run Code Online (Sandbox Code Playgroud)
太糟糕了,我不能在这种方法中使用该data属性@RouteConfig.感觉会好一些.
我已经在一段时间内遇到了类似的问题.我发现的解决方案起初可能会被视为棘手,但可以在将来为我解决此类问题.
基本上,您必须router-outlet在路由更改时发出一个事件,让您AppComponent收听该自定义事件.
第一步是创建自定义路由器插座:
@Directive({
selector: 'custom-router-outlet'
})
export class CustomRouterOutlet extends RouterOutlet {
private parentRouter:Router;
constructor(_elementRef: ElementRef,
_loader: DynamicComponentLoader,
_parentRouter: Router,
@Attribute('name') nameAttr: string) {
super(_elementRef, _loader, _parentRouter, nameAttr);
this.parentRouter = _parentRouter;
}
activate(nextInstruction: ComponentInstruction): Promise<any> {
//***YOUR CUSTOM LOGIC HERE***
return super.activate(nextInstruction);
}
}
Run Code Online (Sandbox Code Playgroud)
这是自定义路由器插座的一个非常基本的实现.您的逻辑必须在activate方法中实现,在每次路由更改时调用.在此方法中,您可以检查路径中的数据属性.
主要问题是,目前,指令不能发出事件......它们只接受输入,不能触发任何输出......
我找到了解决此问题的方法:使用以下方法为组件和指令之间的通信创建服务EventEmitter:
@Injectable()
export class PubsubService {
private _pubSubber: EventEmitter<any> = new EventEmitter();
routeisChanging(obj:any) {
this._pubSubber.emit(obj);
}
onRouteChanged() {
return this._pubSubber;
}
}
Run Code Online (Sandbox Code Playgroud)
该AppComponent订阅的onRouteChanged事件:
subscription:any;
constructor(private _pubsubService:PubsubService) {
this.subscription = this._pubsubService.onRouteChanged().subscribe(data => {
/**YOUR CUSTOM LOGIC HERE*/});
}
Run Code Online (Sandbox Code Playgroud)
该CustomRouterOutlet触发的事件activate需要时方法:
activate(nextInstruction: ComponentInstruction): Promise<any> {
//***YOUR CUSTOM LOGIC HERE***
this._pubsubService.routeisChanging(nextInstruction.routeData.data['hideTopbar']);
return super.activate(nextInstruction);
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以轻松地实现路由器AppComponent与任何逻辑之间的通信.
您必须记住在RootComponent您的应用程序中注入通信服务.
| 归档时间: |
|
| 查看次数: |
2668 次 |
| 最近记录: |