내 응용 프로그램에는 다음이 있습니다 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 { }
보시다시피, "제품"이라고 부르는 두 가지가 있는데, "forms"와 "admin"이며 각각 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>
있습니다. 문제는이 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;
}));
}
}
따라서 navbar 콘텐츠는 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으로 설정되므로 navbar는 제품이 업데이트되었음을 알게됩니다.
그러나 문제는 매우 간단하며 navbar 내의 구독이 트리거되지 않습니다.
(편집 : 버그의 일부는를 사용하여 발생했으며으로 private subscription = Subscription.EMPTY;
대체했을 때 작동한다고 명시했습니다 private subscription = new Subscription();
)
우선 NgModule에서 모든 로직을 이동하는 것이 좋습니다. 이것은 나쁜 습관이며 모듈이 존재하지 않습니다.
AdminModule의 construcor에서 currentProduct를 변경하려는 방법을 이해할 수 없습니까? 이것은 작동하지 않습니다. 첫 번째 다운로드 후에는 모듈이 더 이상로드되지 않으므로 생성자가 호출되지 않습니다.
URL 변경 이벤트를 구독 할 수 있습니다. navbar 구성 요소에서 :
if (this.router.url.startsWith(`/forms`)) {
this.currentProduct = ProductEnum.Forms;
} else if (this.router.url.startsWith(`/admin`)) {
this.currentProduct ProductEnum.Admin;
}
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
if (event.url.startsWith(`/forms`)) {
this.currentProduct = ProductEnum.Forms;
} else if (event.url.startsWith(`/admin`)) {
this.currentProduct = ProductEnum.Admin;
}
}
})
그러나 내가 당신이라면 navbar에서 "페이지 유형"(관리자 또는 양식 또는 다른 것) 매개 변수를 정의하고이 navbar를 모듈의 루트 페이지로 전송하고 하위 페이지에 대한 콘센트를 만들 것입니다 (추가하지 않도록 각 페이지로 이동)
BehaviorSubject 대신 Subject를 사용하는 경우
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다