zoukankan      html  css  js  c++  java
  • 使用angular4和asp.net core 2 web api做个练习项目(四)

    第一部分: http://www.cnblogs.com/cgzl/p/7755801.html

    第二部分: http://www.cnblogs.com/cgzl/p/7763397.html

    第三部分: http://www.cnblogs.com/cgzl/p/7768147.html

    后台代码: https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplate

    前台代码: https://github.com/solenovex/angular-4-client-panel-app

    Auth Guard

    该系统的大部分页面都应该是用户登陆以后才可以看见, 没有登陆的话直接应该跳转到登陆页面.

    首先建立authguard:

    ng g g guards/auth

    代码:

    import { Injectable } from '@angular/core';
    import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/map';
    import { User } from 'oidc-client';
    import { AuthService } from '../services/auth.service';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
    
      constructor(
        private router: Router,
        private authService: AuthService
      ) { }
    
      canActivate(): Observable<boolean> {
        return this.authService.loginStatusChanged.map((user: User) => {
          if (user) {
            return true;
          }
          this.authService.login();
          return false;
        });
      }
    }

    然后在app.module.ts里面引用并注册:

    import { AuthGuard } from './guards/auth.guard';
    
    const appRoutes: Routes = [
      { path: '', component: DashboardComponent, canActivate: [AuthGuard] },
      { path: 'login-callback', component: LoginCallbackComponent },
      { path: 'register', component: RegisterComponent },
      { path: 'add-client', component: AddClientComponent, canActivate: [AuthGuard] },
      { path: 'client/:id', component: ClientDetailsComponent, canActivate: [AuthGuard] },
      { path: 'edit-client/:id', component: EditClientComponent, canActivate: [AuthGuard] }
    ];
    
      providers: [
        ClientService,
        AuthService,
        AuthGuard
      ],

    需要权限控制的路由需要加上 canActivate属性, 它的值是一个数组可以使用多个guards.

    别忘了在providers里面注册一下.

    然后运行.

    进入首页 http://localhost:4200, 如果没登陆, 那么直接跳转到authorization server的登陆页面.

    登录成功后, 会跳转到login-callback, 这里有一个地方需要改一下(可能是oidc-client的bug?):

    ngOnInit() {
        this.authService.loginCallBack().subscribe(
          (user: User) => {
            if (user) {
              window.location.href = '/';
            }
          }
        );
      }

    使用的是window.location.href='/', 如果使用angular的路由router.navigate跳转的话会有问题.

    登陆成功后跳转到主页.

    做一些清理工作:

    由于用户注册是在authorization server进行的, 所以把angular项目中的相关文件以及app.module里面的调用删除...

    Settings 系统设置

    我们需要做一些全局的设置, 可以全局控制某些参数, 例如我们的余额是否可以输入.

    建立settings service:

    ng g s services/settings

    建立settings model:

    ng g interface models/Settings

    生成的文件名首字母是小写的, 首字母还是改成大写的吧...

    Settings.ts:

    export interface Settings {
      disableBalanceOnAdd?: boolean;
      disableBalanceOnEdit?: boolean;
    }

    settings.service.ts:

    import { Injectable } from '@angular/core';
    import { Settings } from '../models/Settings';
    
    @Injectable()
    export class SettingsService {
    
      private _settings: Settings = {
        disableBalanceOnAdd: false,
        disableBalanceOnEdit: false
      };
    
      constructor() { }
    
      get settings() {
        return this._settings;
      }
    }

    然后再app.module.ts里面注册:

    import { SettingsService } from './services/settings.service';
    providers: [
    
        ClientService,
        AuthService,
        SettingsService,
        AuthGuard
      ]

    然后我们使用settings service.

    在add-client.component.ts里面:

    import { SettingsService } from '../../services/settings.service';
    
    public disableBalanceOnAdd = false;
    
      constructor(
        public flashMessagesService: FlashMessagesService,
        public router: Router,
        public clientService: ClientService,
        public settingsService: SettingsService
      ) { }
    
      ngOnInit() {
        this.disableBalanceOnAdd = this.settingsService.settings.disableBalanceOnAdd;
      }

    然后运行一下:

    发现点击添加按钮不起作用!!!!, 点击明细也不起作用!!!!

    后来发现, 是auth service和auth guard里面写错了, 先修改auth service:

      tryGetUser() {
        return Observable.fromPromise(this.manager.getUser());
      }

    把这个方法改成public的.

    然后修改: auth guard:

      canActivate(): Observable<boolean> {
        return this.authService.tryGetUser().map((user: User) => {
          if (user) {
            return true;
          }
          this.authService.login();
          return false;
        });
      }

    这次再试试, 就没有问题了. 进入添加客户页面.

    这个栏位的状态会根据settings里面的设置而变化.

    同样在edit-client里面修改一下:

    import { SettingsService } from '../../services/settings.service';
    
    disableBalanceOnEdit = false;
    
      constructor(
        public clientService: ClientService,
        public router: Router,
        public route: ActivatedRoute,
        public flashMessagesService: FlashMessagesService,
        public settingsService: SettingsService
      ) { }
    
      ngOnInit() {
        this.disableBalanceOnEdit = this.settingsService.settings.disableBalanceOnEdit;
        // 获取ID
        this.id = this.route.snapshot.params['id'];
        // 获取Client
        this.clientService.getOne(+this.id).subscribe(
          client => {
            this.client = client;
          }
        );
      }

    运行一下, 应该好用!

    最后, 做一下Settings页面

    需要改一下setting.serviec, 将使用localstorage来存储settings:

    import { Injectable } from '@angular/core';
    import { Settings } from '../models/Settings';
    
    @Injectable()
    export class SettingsService {
    
      private _settings: Settings = {
        disableBalanceOnAdd: true,
        disableBalanceOnEdit: false
      };
    
      constructor() {
        if (localStorage.getItem('settings')) {
          this._settings = JSON.parse(localStorage.getItem('settings'));
        }
      }
    
      get settings() {
        return this._settings;
      }
    
      set settings(value: Settings) {
        this._settings = value;
        localStorage.setItem('settings', JSON.stringify(this._settings));
      }
    }

    然后打开settings.component.ts:

    import { Component, OnInit } from '@angular/core';
    import { SettingsService } from '../../services/settings.service';
    import { Router } from '@angular/router';
    import { FlashMessagesService } from 'angular2-flash-messages';
    import { Settings } from '../../models/Settings';
    
    @Component({
      selector: 'app-settings',
      templateUrl: './settings.component.html',
      styleUrls: ['./settings.component.css']
    })
    export class SettingsComponent implements OnInit {
    
      settings: Settings;
    
      constructor(
        private settingsService: SettingsService,
        private flashMessagesService: FlashMessagesService,
        private router: Router
      ) { }
    
      ngOnInit() {
        this.settings = this.settingsService.settings;
      }
    
      onSubmit() {
        this.settingsService.settings = this.settings;
        this.flashMessagesService.show('Settings 保存了', { cssClass: 'alert-success', timeout: 4000 });
      }
    
    }

    这个很简单.

    然后是html:

    <div class="row">
      <div class="col-md-6">
        <a routerLink="/" class="btn btn-link">
          <i class="fa fa-arrow-circle-o-left"></i> 回到Dashboard</a>
      </div>
      <div class="col-md-6">
    
      </div>
    </div>
    
    <div class="card">
      <div class="card-header">
        <h3>编辑 Settings</h3>
      </div>
      <div class="card-body">
        <form (submit)="onSubmit()">
          <div class="form-group">
            <label for="disableBalanceOnAdd">Disable Blance on Add</label>
            <input type="checkbox" id="disableBalanceOnAdd" name="disableBalanceOnAdd" [(ngModel)]="settings.disableBalanceOnAdd">
          </div>
          <div class="form-group">
            <label for="disableBalanceOnEdit">Disable Blance on Edit</label>
            <input type="checkbox" id="disableBalanceOnEdit" name="disableBalanceOnEdit" [(ngModel)]="settings.disableBalanceOnEdit">
          </div>
          <input type="submit" class="btn btn-primary btn-block" value="Submit">
        </form>
      </div>
    </div>

    别忘了在app.module里面添加路由:

    const appRoutes: Routes = [
      { path: '', component: DashboardComponent, canActivate: [AuthGuard] },
      { path: 'login-callback', component: LoginCallbackComponent },
      { path: 'add-client', component: AddClientComponent, canActivate: [AuthGuard] },
      { path: 'client/:id', component: ClientDetailsComponent, canActivate: [AuthGuard] },
      { path: 'edit-client/:id', component: EditClientComponent, canActivate: [AuthGuard] },
      { path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
      { path: '**', component: PageNotFoundComponent }
    ];

    顺便把page Not found的路由也加上, 使用 ** wildcard.

    最后在navbar.html 添加上链接按钮:

            <li *ngIf="isLoggedIn" class="nav-item">
              <a class="nav-link" href="#" routerLink="/settings">Settings </a>
            </li>

    运行一下试试:

    刷新, 查看添加和编辑页面,再刷新, 应该好用.

    这个联系项目就到这了.

    然后我要用asp.net core 2.0 web api 和 identity server 4 以及 angular 5 做一个项目了(angular 5正式版刚刚出来), 大约 300个页面......

    也许之前还要做一个练习..请各位指教...

  • 相关阅读:
    Linux内核同步方法
    C++11写轻量级AOP框架
    Typora夜樱主题
    MySQL添加主键和外键
    命题连接词和命题逻辑
    打印一个类全部信息的方法
    getClass()和instanceof以及类的equals方法
    多态
    在构造函数中调用另一个构造函数
    参数传递
  • 原文地址:https://www.cnblogs.com/cgzl/p/7776378.html
Copyright © 2011-2022 走看看