我的应用程序具有以下内容app-routing.module.ts
:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PageNotFoundComponent } from './core/page-not-found/page-not-found.component';
const routes: Routes = [
{ path: '', redirectTo: 'forms', pathMatch: 'full' },
{ path: 'forms', loadChildren : () => import('./pages/forms/forms.module').then(m => m.FormsModule) },
{ path: 'admin', loadChildren : () => import('./pages/admin/admin.module').then(m => m.AdminModule) },
{ path: '**', component: PageNotFoundComponent }
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
如您所见,我有两个我称之为“产品”的东西,它们是“表单”和“管理员”,它们分别由 url /forms 和 /admin 访问。
app.component.html
如下:
<navbar></navbar>
<div class="container">
<ngx-spinner
bdColor = "rgba(51, 51, 51, 0.6)"
size = "large"
color = "white"
type = "ball-running-dots">
<p style="font-size: 20px; color: white">Loading...</p>
</ngx-spinner>
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
如您所见,我有组件“导航栏”,标记为<navbar></navbar>
. 问题是,这个导航栏的内容会根据用户所在的产品而有所不同。为了让事情更清楚,让我们看一下navbar.component.html
:
<default-navbar *ngIf="currentProduct == 'forms'"></default-navbar>
<div *ngIf="currentProduct != 'forms'">
lalalallala
</div>
而且在navbar.component.ts
:
import { OnInit, OnDestroy, Component } from '@angular/core';
import { Subscription } from '../../../../../node_modules/rxjs';
import { ProductEnum } from '../../../shared/models/enums/product-enum';
import { ProductContainer } from '../../../shared/containers/product-container';
@Component({
selector: 'navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit, OnDestroy
{
public currentProduct:ProductEnum;
private subscription = Subscription.EMPTY;
constructor(private _productContainer:ProductContainer)
{
}
ngOnInit(): void
{
this.currentProduct = this._productContainer.getCurrentProduct();
this.initializeSubscribers();
}
ngOnDestroy(): void
{
this.subscription.unsubscribe();
}
private initializeSubscribers():void
{
this.subscription.add(this._productContainer.getChangeCurrentProductSubject().subscribe(_newCurrentProduct => {
this.currentProduct = _newCurrentProduct;
}));
}
}
因此导航栏内容会因currentProduct
属性而异。这个变量将由我调用的可注入服务上存在的主题属性更新ProductContainer
(顺便说一句,我知道这个名字很糟糕)。
这是ProductContainer
(product-container.ts
)代码:
import { Injectable } from '@angular/core';
import { Subject } from '../../../../node_modules/rxjs';
import { ProductEnum } from '../models/enums/product-enum';
@Injectable({
providedIn: 'root',
})
export class ProductContainer
{
private changeCurrentProductSubject: Subject<ProductEnum> = new Subject<ProductEnum>();
private currentProduct: ProductEnum = ProductEnum.Forms;
public setCurrentProduct(_newCurrentProduct:ProductEnum):void
{
this.currentProduct = _newCurrentProduct;
this.changeCurrentProductSubject.next(this.currentProduct);
}
public getCurrentProduct():ProductEnum
{
return this.currentProduct;
}
public getChangeCurrentProductSubject():Subject<ProductEnum>
{
return this.changeCurrentProductSubject;
}
}
所以如果我们回到app-routing.module.ts
,我们可以看到当 \admin url 被访问时,AdminModule
被加载了。这是AdminModule
代码:
import { CommonModule } from '@angular/common';
import { SharedModule } from '../../shared/shared.module';
import { NgModule } from '@angular/core';
import { AdminRoutingModule } from './admin-routing.module';
import { AdminHomeModule } from './admin-home/admin-home.module';
import { CoreModule } from '../../core/core.module';
import { ProductContainer } from '../../shared/containers/product-container';
import { ProductEnum } from '../../shared/models/enums/product-enum';
import { Router, RouterModule } from '@angular/router';
@NgModule({
declarations: [],
imports: [
CommonModule,
SharedModule,
AdminRoutingModule,
AdminHomeModule,
CoreModule,
RouterModule
]
})
export class AdminModule
{
constructor(private _productContainer:ProductContainer, private router: Router)
{
this._productContainer.setCurrentProduct(ProductEnum.Admin);
}
}
因此,当访问 \admin url 时,它会将当前产品设置为 Admin,因此导航栏将知道产品已更新。
但问题很简单,导航栏中的订阅没有被触发。
(编辑:部分错误也是由使用引起的private subscription = Subscription.EMPTY;
,当我替换为时它表示工作private subscription = new Subscription();
)