我们有一个MVC登录站点,一旦成功登录就会加载一个角度4应用程序。我们使用的是mvc控制器,它有一个保存用户数据的会话管理器。什么是我的角度2应用程序获取和保存此数据的最佳方式?目前,我有UserId和UserStatus的全球服务。需要UserStatus来控制对站点部分的访问,包括隐藏或显示一些导航菜单链接。
问题是在页面呈现之前未完成调用,因此菜单没有更新,网站的主页显示所有控件。如果我点击其他页面然后返回该网站的主页,则根据用户的状态正确隐藏部分。我创建了一个似乎模拟它的简单plnkr。 https://plnkr.co/edit/NHgoMi?p=preview
我添加了一个setTimeout变量来模拟从服务器获取数据的延迟。请注意,具有setTimeout的那个在页面加载之前尚未完成,因此它显示错误的值。
有没有办法延迟应用程序加载或主组件的呈现,直到从服务器检索权限?
这是plnkr文件:
main.ts:
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';
import { SessionService } from './session.service';
platformBrowserDynamic().bootstrapModule(AppModule, [SessionService])
app.ts
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {SessionService } from './session.service';
import { LayoutModule } from './layout.module';
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<layout></layout>
</div>
`,
providers:[
SessionService
]
})
export class App {
name:string;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
}
@NgModule({
imports: [
BrowserModule,
LayoutModule
],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
home.componenet.ts
import { Component, OnInit } from '@angular/core';
import { NgControl } from '@angular/forms';
import { SessionService } from './session.service';
@Component({
selector: 'home',
template: '<p>userStatus: {{userStatus}}</p><p>userStatusWithTimeout: {{userStatusWithTimeout}}</p>'
})
export class HomeComponent implements OnInit {
userStatus: boolean;
userStatusWithTimeout: boolean;
constructor(private _sessionService: SessionService) {
}
ngOnInit(): void {
this.userStatus = this._sessionService.getUserStatus();
this.userStatusWithTimeout = this._sessionService.getUserStatusWithTimeout();
}
}
layout.componenet.ts
import { Component } from '@angular/core';
import { NgControl } from '@angular/forms';
@Component({
selector: 'layout',
template: '<home></home>'
})
export class LayoutComponent {}
layout.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
//components
import { HomeComponent } from './home.component';
import { LayoutComponent } from './layout.component';
@NgModule({
imports: [
BrowserModule
],
declarations:
[
HomeComponent,
LayoutComponent
],
exports: [
LayoutComponent,
HomeComponent
],
providers: [
]
})
export class LayoutModule {}
session.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
@Injectable()
export class SessionService { // extends ServiceAdapter {
private _userStatus: boolean = false;
private _userStatusWithTimeout: boolean = false;
private _userID: number;
private _getSessionUserID = 'Session/GetSessionUserID';
private _getIsSessionUserStatus = 'Session/GetIsSessionUserStatus';
constructor() {
this.setSessionVariables();
}
setSessionVariables() {
this.loadUserID()
.do(data => console.log("loading id: ", data))
.subscribe(result => this._userID = result);
this.loadUserStatus()
.do(data => console.log("loading status: ", data))
.subscribe(result => this._userStatus = result);
this.loadUserStatusWithTimeout()
.do(data => console.log("loading status with timeout: ", data))
.subscribe(result => this._userStatusWithTimeout = result);
}
loadUserID(): Observable<number> {
return Observable.of(setTimeout(() => { 1 }, 1000)) // this.getaction<number>(this._getSessionUserID);
}
loadUserStatus(): Observable<boolean> {
return Observable.of(true) //this.getaction<number>(this._getIsSessionUserStatus);
}
loadUserStatusWithTimeout(): Observable<boolean> {
console.log("setting temp", this._userStatusWithTimeout);
setTimeout(() => { this._userStatusWithTimeout = true }, 1000)
console.log("temp is set", this._userStatusWithTimeout);
return Observable.of(this._userStatusWithTimeout) //this.getaction<number>(this._getIsSessionUserStatus);
}
getUserID(): number {
return this._userID;
}
getUserStatus(): boolean {
return this._userStatus;
}
getUserStatusWithTimeout(): boolean {
return this._userStatusWithTimeout;
}
}
答案 0 :(得分:1)
在获取会话数据后,不要隐藏受限制的UI,而是在验证用户应该看到它后显示受限制的UI。这将阻止用户不应该看到闪烁和消失的控件。如果在新元素出现时创建一些jank,请考虑围绕它设计的加载状态。
Angular中加载状态的最基本实现是在请求启动时在组件或服务上将isLoading
标志设置为true,然后在完成时将其设置为false。然后在模板中的元素上添加*ngIf='service.isLoading'
并 voila 。
以下是我为分页服务制作的一个简单示例:service / template / result。
此外,如果您使用MVC框架为Angular应用程序提供服务,则可以在Angular的索引页面窗口中将您的权限作为JavaScript对象嵌入,以使它们立即可供您的应用程序使用#39;的许可/会话服务。这将在您获取权限时避免任何加载延迟,但将采取其他配置以使您的服务器代码在Angular启动页面中工作。