使用angular 2 app登录mvc的会话数据

时间:2017-07-06 20:59:19

标签: asp.net-mvc angular asp.net-mvc-4 angular2-services

我们有一个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;
        }
    }

1 个答案:

答案 0 :(得分:1)

在获取会话数据后,不要隐藏受限制的UI,而是在验证用户应该看到它后显示受限制的UI。这将阻止用户不应该看到闪烁和消失的控件。如果在新元素出现时创建一些jank,请考虑围绕它设计的加载状态。

Angular中加载状态的最基本实现是在请求启动时在组件或服务上将isLoading标志设置为true,然后在完成时将其设置为false。然后在模板中的元素上添加*ngIf='service.isLoading' voila 。 以下是我为分页服务制作的一个简单示例:service / template / result

此外,如果您使用MVC框架为Angular应用程序提供服务,则可以在Angular的索引页面窗口中将您的权限作为JavaScript对象嵌入,以使它们立即可供您的应用程序使用#39;的许可/会话服务。这将在您获取权限时避免任何加载延迟,但将采取其他配置以使您的服务器代码在Angular启动页面中工作。