我被要求在不 destruct 任何逻辑的情况下更新项目的UI(我 destruct 了). 在旧的UI验证(登录页面)和其他(在身份验证后可以访问的其他资源)是在相同的布局中(头+内容+页脚),但在新的一个验证页面有一个不同的布局与应用程序布局(登录后). 所以我以这样的方式分离布局:
RouterModule.forRoot([
{ path: 'auth', component: AuthLayoutComponent,
children: [
{ path: '', component: AuthHomeComponent },
{ path: 'login', component: LoginComponent},
{ path: 'terms-of-use', component: TermsOfUseComponent},
{ path: 'contact', component: AuthContactFormComponent}
]
},
{ path: '', component: HomeComponent,
children: [
{ path: 'contact', component: ContactFormComponent },...]
bootstrap: [AppComponent]
HomeComponent
是用于应用的布局,而AuthLayoutComponent
是用于认证部分的布局.
旧配置:
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'contact', component: ContactFormComponent },
...]
bootstrap: [AppComponent]
新AppComponent
:
<ng-container>
<router-outlet></router-outlet>
<sac-alert></sac-alert>
<sac-loader></sac-loader>
</ng-container>
老AppComponent
:
<app-header></app-header>
<div class="body-content">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
新HomeComponent
:
<div class="admin-container">
<app-navigation></app-navigation>
<div class="admin-section-container">
<app-header></app-header>
<main>
<ng-container>
<router-outlet></router-outlet>
</ng-container>
</main>
</div>
</div>
一切都如预期的那样工作,直到我注意到HeaderComponent
在登录后并不显示登录用户的姓名和姓氏,而在旧版本中,它会立即出现在右上角.
HeaderComponent
:
<div ngbDropdown class="d-inline-block dropdown" *ngIf="isLoggedIn && user">
<button type="button" class="btn" ngbDropdownToggle id="userDropdown">
<img src="assets/icons/combo shape.svg" alt=""> <span *ngIf="user.surname">{{user.surname}}</span>
<span *ngIf="user.name">{{user.name}}</span>
</button>
HeaderComponent.ts
:
constructor(
private apiService: ApiService,
public entityMapService: EntityMapService,
public changeNotificationsService: ChangeNotificationsService,
public router: Router,
public cdr: ChangeDetectorRef
) {
this.isProduction = environment.production === true;
this.apiService.currentUserChanged.subscribe(user => {
this.user = user;
this.isLoggedIn = this.user != null;
});
}
currentUserChanged
在ApiService
:
public currentUser: UserInfo;
private currentUserChangeObservers: Observer<UserInfo>[] = [];
public currentUserChanged = new Observable<UserInfo>(observer => {
this.currentUserChangeObservers.push(observer);
});
UserInfo
只是一个界面.
现在,正如我在旧版本中所说的,只要你登录,你的名字就会出现在HeaderComponent
的右上角,但是在移动HeaderComponent
到不同的布局而不改变其任何类型代码之后,它不显示用户名和姓没有页面重新加载(f5).所以在登录后,我需要刷新页面以进行更改.
使用console.log,我看到HeaderComponent中的订阅逻辑运行良好(user不是null),但是当ngOnInit中的console.log(this.user)
时,我注意到它给出了null
.
在HeaderComponent
的构造器中:
this.apiService.currentUserChanged.subscribe(user => {
this.user = user;
console.log(this.user)//gives actual object
this.isLoggedIn = this.user != null;
});
}
刷新后,它工作正常,但它不应该这样工作,是吗?
我试过:
- 使用ChangeDetectionRef手动变更检测.detectChanges和markForCheck都使用了.
- 在HeaderComponent中使用NgZone.run().在其中运行订阅逻辑以关联更改.
- HeaderComponent中的Applicationatoin. ref()
- 在AfterViewInit、OnInit、NgDoCheck中编写了相同的订阅逻辑.什么都没有用.
- No ChangeDetectionStrategy在父组件中的任何地方都不会设置为OnPush.
在try 和测试代码之后,我发现当我将HeaderComponent
移到AuthLayoutComponent
的子部分(或者只是将其粘贴在AuthLayoutComponent
中)时,它在使用相同的打字脚本时没有任何问题.从这里,我确定问题是由于在路由配置中使用了不同的布局和子属性.我知道这个问题,但我不知道如何在保留新UI的同时解决它.
有谁知道为什么ChangeDetection不工作而不刷新页面时,使用不同的布局?(服务是共享的,因此它们应该检测到更改).
我try 将RouteConfiguration更改为此,但ChangeDetection仍然需要页面刷新:
const routes: Routes = [
{
path: '',
children: [
{
path: 'auth',
component: AuthLayoutComponent,
children: [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{ path: 'terms-of-use', component: TermsOfUseComponent },
{ path: 'contact', component: AuthContactFormComponent }
]
},
{
path: 'home',
component: HomeComponent,
children: [
]
},
{ path: '', redirectTo: 'home', pathMatch: 'full' },
]
},
Angular 17.3.0,Zone.js 0.14.4