溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ASP.NET Core中如何使用Angular2

發(fā)布時(shí)間:2021-08-27 13:59:52 來(lái)源:億速云 閱讀:117 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)ASP.NET Core中如何使用Angular2的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

Angular2是對(duì)Angular1的一次徹底的,破壞性的更新。

相對(duì)于Angular1.x,借用某果的廣告語(yǔ),唯一的不同,就是處處都不同。

?首先,推薦的語(yǔ)言已經(jīng)不再是Javascript,取而代之的TypeScript,(TypeScript = ES6 + 類型系統(tǒng) + 類型注解), TypeScriipt的類型系統(tǒng)對(duì)于開(kāi)發(fā)復(fù)雜的單頁(yè)Web app大有幫助,同時(shí)編譯成javascript后的執(zhí)行效率也比大多數(shù)手寫(xiě)javascript要快。

?得益于徹底重構(gòu),性能相對(duì)于Angular1.x有了大幅提升,也更適合再全平臺(tái)部署。

?Angular2是基于Component的,Component可以理解為是1.x時(shí)代的Controller + $Scope + view

?View的很多語(yǔ)法也做了更新,比如<li ng-repeat="movie in vm.movies"></li> 變成了 <li *ngFor="let movie of movies"></li>

1.前期準(zhǔn)備

?推薦使用VS2015 Update3或更新的版本完成本示例,下載地址:https://www.jb51.net/softjc/446184.html

?你需要安裝.NET Core開(kāi)發(fā)環(huán)境,這里提供VS版: https://www.jb51.net/softs/472362.html

?安裝Node.js 版本5.0.0或以上,(在本例中,這個(gè)主要是編譯TypeScript用的)下載地址:Node.js and NPM

?NPM 3.0.0或以上,默認(rèn)NPM會(huì)隨著Node.js一并安裝完畢。(在本例中,這個(gè)主要是下載各種Angular的各個(gè)包用的,參考VS中的Nuget)

2.創(chuàng)建項(xiàng)目

在VS中新建項(xiàng)目,項(xiàng)目類型選擇 ASP.NET Core Web Application(.Net Core),輸入項(xiàng)目名稱為:CSAuthorAngular2InASPNetCore,Template選擇為Empty.

3.在項(xiàng)目中整合Angular2

3.1.配置Startup.cs

注:添加下面的代碼時(shí)IDE會(huì)報(bào)代碼錯(cuò)誤,這是因?yàn)檫€沒(méi)有引用對(duì)用的包,進(jìn)入報(bào)錯(cuò)的這一行,點(diǎn)擊燈泡,加載對(duì)應(yīng)的包就可以了。

ASP.NET Core中如何使用Angular2

(圖文無(wú)關(guān))

在ConfigureServices中添加如下代碼

services.AddMvc();

這里是添加MVC服務(wù)

在Configure中添加如下代碼

app.UseStaticFiles();

app.UseMvc(routes =>
{
  routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}");
});

第一句是啟用靜態(tài)文件,第二句是應(yīng)用MVC模式并添加路由配置。

完整的代碼應(yīng)該是這個(gè)樣子

public class Startup
{
  // This method gets called by the runtime. Use this method to add services to the container.
  // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddMvc();
  }

  // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
  {
    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
      routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}");
    });
  }
}

3.2.添加控制器以及視圖

3.2.1.在項(xiàng)目根目錄下添加Controllers目錄,并在其中添加一個(gè)控制器HomeController.cs,默認(rèn)代碼即可。

3.2.2.在項(xiàng)目跟目錄下創(chuàng)建Views目錄,在Views目錄中新建目錄Home, 最后在Home目錄中新建視圖Index.cshtml,內(nèi)容應(yīng)該是這樣:

<html>
<head>
  <title>Angular QuickStart</title>
  <base href="/">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- 1. Load libraries -->
  <!-- Polyfill(s) for older browsers -->
  <script src="node_modules/core-js/client/shim.min.js"></script>
  <script src="node_modules/zone.js/dist/zone.js"></script>
  <script src="node_modules/reflect-metadata/Reflect.js"></script>
  <script src="node_modules/systemjs/dist/system.src.js"></script>
  <!-- 2. Configure SystemJS -->
  <script src="systemjs.config.js"></script>
  <script>
   System.import('app').catch(function(err){ console.error(err); });
  </script>
</head>
<!-- 3. Display the application -->
<body>
  <my-app>Loading...</my-app>
</body>
</html>

現(xiàn)在運(yùn)行項(xiàng)目的話你僅僅能看到一個(gè)Loading,再控制臺(tái)中你還能看到錯(cuò)誤,這是因?yàn)槲覀冞€沒(méi)有配置Angular。讓我們前往wwwroot目錄。

3.3.在項(xiàng)目的wwwroot目錄中添加如下結(jié)構(gòu):

3.3.1搭建Angular2基礎(chǔ)環(huán)境

?package.json

{
 "name": "angular-quickstart",
 "version": "1.0.0",
 "scripts": {
  "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
  "lite": "lite-server",
  "postinstall": "typings install",
  "tsc": "tsc",
  "tsc:w": "tsc -w",
  "typings": "typings"
 },
 "licenses": [
  {
   "type": "MIT",
   "url": "https://github.com/angular/angular.io/blob/master/LICENSE"
  }
 ],
 "dependencies": {
  "@angular/common": "2.0.2",
  "@angular/compiler": "2.0.2",
  "@angular/core": "2.0.2",
  "@angular/forms": "2.0.2",
  "@angular/http": "2.0.2",
  "@angular/platform-browser": "2.0.2",
  "@angular/platform-browser-dynamic": "2.0.2",
  "@angular/router": "3.0.2",
  "@angular/upgrade": "2.0.2",
  "angular-in-memory-web-api": "0.1.5",
  "bootstrap": "3.3.7",
  "core-js": "2.4.1",
  "reflect-metadata": "0.1.8",
  "rxjs": "5.0.0-beta.12",
  "systemjs": "0.19.39",
  "zone.js": "0.6.25"
 },
 "devDependencies": {
  "concurrently": "3.0.0",
  "gulp": "^3.9.1",
  "lite-server": "2.2.2",
  "typescript": "2.0.3",
  "typings": "1.4.0"
 }
}

?systemjs.config.js

(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      app: 'app',
      // angular bundles
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
      '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
      // other libraries
      'rxjs': 'npm:rxjs',
      'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        main: './main.js',
        defaultExtension: 'js'
      },
      rxjs: {
        defaultExtension: 'js'
      }
    }
  });
})(this);

?tsconfig.js

{
 "compileOnSave": true,
 "compilerOptions": {
  "target": "es5",
  "module": "commonjs",
  "moduleResolution": "node",
  "sourceMap": true,
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true,
  "removeComments": false,
  "noImplicitAny": false
 },
 "exclude": [
  "node_modules"
 ]
}

?typings.json(注,在最新文檔中typings已被npm的@types替代,參見(jiàn)官方文檔:文檔變更日志)

{
 "globalDependencies": {
  "core-js": "registry:dt/core-js#0.0.0+20160725163759",
  "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
  "node": "registry:dt/node#6.0.0+20160909174046"
 }
}

右擊wwwroot中的Package.json,選擇Restore Packages(或者在CMD下進(jìn)入wwwroot目錄,并執(zhí)行命令 npm install),npm會(huì)去下載需要的包,并存儲(chǔ)于node_modules目錄中。

ASP.NET Core中如何使用Angular2

3.3.2.配置啟動(dòng)文件以啟用Angular2

在wwwroot下新建目錄app,app擁有如下文件:

?app.component.ts

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'my-app',
  template: "this is in angular2",
})
export class AppComponent {
}

可以發(fā)現(xiàn)被@Component裝飾屬性裝飾了AppComponent,selector指代你Component的占位符,比如本例中你可以再Home/index.cshtml中發(fā)現(xiàn)一段這樣的標(biāo)記

<my-app>Loading...</my-app>

template既為該Component的View,不要忘記moduleId,不添加它會(huì)出現(xiàn)很多奇怪的問(wèn)題。

?app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";

import { AppComponent } from "./app.component";

@NgModule({
  bootstrap: [AppComponent],
  imports: [
    BrowserModule
  ],
  declarations: [
    AppComponent
  ]
})
export class AppModule { }

?main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

基礎(chǔ)整合完畢。

按F5 Debug一下,現(xiàn)在你能再瀏覽器中看到一句話:this is in angular 2

ASP.NET Core中如何使用Angular2

4.實(shí)現(xiàn)身份認(rèn)證

廢了半天勁,看著很傻,沒(méi)有任何成就感。怎么辦,讓我們?cè)偕钊胍稽c(diǎn),接下來(lái)我們來(lái)為Angular2完成一個(gè)Token base的身份驗(yàn)證,我會(huì)把Angular2的routing,data bind,service,http,等等你工作中最常用到的挨個(gè)演示一遍。

4.1.Server端

4.1.1.創(chuàng)建一些輔助類

4.1.1.1.在項(xiàng)目根目錄下創(chuàng)建一個(gè)文件夾Auth,并添加RSAKeyHelper.cs以及TokenAuthOption.cs兩個(gè)文件

?在RSAKeyHelper.cs中

using System.Security.Cryptography;

namespace CSTokenBaseAuth.Auth
{
  public class RSAKeyHelper
  {
    public static RSAParameters GenerateKey()
    {
      using (var key = new RSACryptoServiceProvider(2048))
      {
        return key.ExportParameters(true);
      }
    }
  }
}

?在TokenAuthOption.cs中

using System;
using Microsoft.IdentityModel.Tokens;

namespace CSTokenBaseAuth.Auth
{
  public class TokenAuthOption
  {
    public static string Audience { get; } = "ExampleAudience";
    public static string Issuer { get; } = "ExampleIssuer";
    public static RsaSecurityKey Key { get; } = new RsaSecurityKey(RSAKeyHelper.GenerateKey());
    public static SigningCredentials SigningCredentials { get; } = new SigningCredentials(Key, SecurityAlgorithms.RsaSha256Signature);

    public static TimeSpan ExpiresSpan { get; } = TimeSpan.FromMinutes(20);
  }
}

4.1.1.2.在項(xiàng)目根目錄下創(chuàng)建目錄Model,并在其中添加RequestResult.cs,代碼應(yīng)該是這樣。

public class RequestResult
{
  public RequestState State { get; set; }
  public string Msg { get; set; }
  public Object Data { get; set; }
}

public enum RequestState
{
  Failed = -1,
  NotAuth = 0,
  Success = 1
}

4.1.2更新Startup.cs

在ConfigureServices中添加如下代碼:

services.AddAuthorization(auth =>
{
  auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
    .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme?)
    .RequireAuthenticatedUser().Build());
});

這里是添加身份認(rèn)證服務(wù)

在Configure方法中添加如下代碼:

app.UseExceptionHandler(appBuilder =>
{
  appBuilder.Use(async (context, next) =>
  {
    var error = context.Features[typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature;

    //when authorization has failed, should retrun a json message to client
    if (error != null && error.Error is SecurityTokenExpiredException)
    {
      context.Response.StatusCode = 401;
      context.Response.ContentType = "application/json";

      await context.Response.WriteAsync(JsonConvert.SerializeObject(new RequestResult
      {
        State = RequestState.NotAuth,
        Msg = "token expired"
      }));
    }
    //when orther error, retrun a error message json to client
    else if (error != null && error.Error != null)
    {
      context.Response.StatusCode = 500;
      context.Response.ContentType = "application/json";
      await context.Response.WriteAsync(JsonConvert.SerializeObject(new RequestResult
      {
        State = RequestState.Failed,
        Msg = error.Error.Message
      }));
    }
    //when no error, do next.
    else await next();
  });
});

本段是Handle當(dāng)身份認(rèn)證失敗時(shí)拋出的異常,并返回合適的json

在相同的方法中添加另外一段代碼:

app.UseJwtBearerAuthentication(new JwtBearerOptions()
{
  TokenValidationParameters = new TokenValidationParameters()
  {
    IssuerSigningKey = TokenAuthOption.Key,
    ValidAudience = TokenAuthOption.Audience,
    ValidIssuer = TokenAuthOption.Issuer,
    // When receiving a token, check that we've signed it.
    ValidateIssuerSigningKey = true,
    // When receiving a token, check that it is still valid.
    ValidateLifetime = true,
    // This defines the maximum allowable clock skew - i.e. provides a tolerance on the token expiry time 
    // when validating the lifetime. As we're creating the tokens locally and validating them on the same 
     // machines which should have synchronised time, this can be set to zero. Where external tokens are
    // used, some leeway here could be useful.
    ClockSkew = TimeSpan.FromMinutes(0)
  }
});

本段代碼是應(yīng)用JWTBearerAuthentication身份認(rèn)證。

4.1.3.TokenAuthController.cs

在Controllers中新建一個(gè)Web API Controller Class,命名為T(mén)okenAuthController.cs。我們將在這里完成登錄授權(quán),

在同文件下添加兩個(gè)類,分別用來(lái)模擬用戶模型,以及用戶存儲(chǔ),代碼應(yīng)該是這樣:

public class User
{
  public Guid ID { get; set; }
  public string Username { get; set; }
  public string Password { get; set; }
}

public static class UserStorage
{
  public static List<User> Users { get; set; } = new List<User> {
    new User {ID=Guid.NewGuid(),Username="user1",Password = "user1psd" },
    new User {ID=Guid.NewGuid(),Username="user2",Password = "user2psd" },
    new User {ID=Guid.NewGuid(),Username="user3",Password = "user3psd" }
  };
}

接下來(lái)在TokenAuthController.cs中添加如下方法

private string GenerateToken(User user, DateTime expires)
{
  var handler = new JwtSecurityTokenHandler();
  
  ClaimsIdentity identity = new ClaimsIdentity(
    new GenericIdentity(user.Username, "TokenAuth"),
    new[] {
      new Claim("ID", user.ID.ToString())
    }
  );

  var securityToken = handler.CreateToken(new SecurityTokenDescriptor
  {
    Issuer = TokenAuthOption.Issuer,
    Audience = TokenAuthOption.Audience,
    SigningCredentials = TokenAuthOption.SigningCredentials,
    Subject = identity,
    Expires = expires
  });
  return handler.WriteToken(securityToken);
}

該方法僅僅只是生成一個(gè)Auth Token,接下來(lái)我們來(lái)添加另外一個(gè)方法來(lái)調(diào)用它

在相同文件中添加如下代碼

[HttpPost]
public string GetAuthToken(User user)
{
  var existUser = UserStorage.Users.FirstOrDefault(u => u.Username == user.Username && u.Password == user.Password);

  if (existUser != null)
  {
    var requestAt = DateTime.Now;
    var expiresIn = requestAt + TokenAuthOption.ExpiresSpan;
    var token = GenerateToken(existUser, expiresIn);

    return JsonConvert.SerializeObject(new {
      stateCode = 1,
      requertAt = requestAt,
      expiresIn = TokenAuthOption.ExpiresSpan.TotalSeconds,
      accessToken = token
    });
  }
  else
  {
    return JsonConvert.SerializeObject(new { stateCode = -1, errors = "Username or password is invalid" });
  }
}

接下來(lái)我們來(lái)完成授權(quán)部分,在相同的文件中添加如下代碼:

public string GetUserInfo()
{
  var claimsIdentity = User.Identity as ClaimsIdentity;

  return JsonConvert.SerializeObject(new RequestResult
  {
    State = RequestState.Success,
    Data = new
    {
      UserName = claimsIdentity.Name
    }
  });
}

為方法添加裝飾屬性

[HttpGet]

[Authorize("Bearer")]

第二行代碼說(shuō)明這個(gè)action需要身份驗(yàn)證。

該文件完整的代碼應(yīng)該是這個(gè)樣子:

using System;
using System.Collections.Generic;
using System.Linq;using Microsoft.AspNetCore.Mvc;
using CSAuthorAngular2InASPNetCore.Auth;
using System.IdentityModel.Tokens.Jwt;
using Newtonsoft.Json;
using System.Security.Claims;
using System.Security.Principal;
using Microsoft.IdentityModel.Tokens;
using CSAuthorAngular2InASPNetCore.Model;
using Microsoft.AspNetCore.Authorization;


namespace CSAuthorAngular2InASPNetCore.Controllers
{
  [Route("api/[controller]")]
  public class TokenAuthController : Controller
  {
    [HttpPost]
    public string GetAuthToken([FromBody]User user)
    {
      var existUser = UserStorage.Users.FirstOrDefault(u => u.Username == user.Username && u.Password == user.Password);

      if (existUser != null)
      {
        var requestAt = DateTime.Now;
        var expiresIn = requestAt + TokenAuthOption.ExpiresSpan;
        var token = GenerateToken(existUser, expiresIn);

        return JsonConvert.SerializeObject(new RequestResult
        {
          State = RequestState.Success,
          Data = new
          {
            requertAt = requestAt,
            expiresIn = TokenAuthOption.ExpiresSpan.TotalSeconds,
            tokeyType = TokenAuthOption.TokenType,
            accessToken = token
          }
        });
      }
      else
      {
        return JsonConvert.SerializeObject(new RequestResult
        {
          State = RequestState.Failed,
          Msg = "Username or password is invalid"
        });
      }
    }

    private string GenerateToken(User user, DateTime expires)
    {
      var handler = new JwtSecurityTokenHandler();

      ClaimsIdentity identity = new ClaimsIdentity(
        new GenericIdentity(user.Username, "TokenAuth"),
        new[] {
          new Claim("ID", user.ID.ToString())
        }
      );

      var securityToken = handler.CreateToken(new SecurityTokenDescriptor
      {
        Issuer = TokenAuthOption.Issuer,
        Audience = TokenAuthOption.Audience,
        SigningCredentials = TokenAuthOption.SigningCredentials,
        Subject = identity,
        Expires = expires
      });
      return handler.WriteToken(securityToken);
    }

    [HttpGet]
    [Authorize("Bearer")]
    public string GetUserInfo()
    {
      var claimsIdentity = User.Identity as ClaimsIdentity;

      return JsonConvert.SerializeObject(new RequestResult
      {
        State = RequestState.Success,
        Data = new
        {
          UserName = claimsIdentity.Name
        }
      });
    }
  }

  public class User
  {
    public Guid ID { get; set; }

    public string Username { get; set; }

    public string Password { get; set; }
  }

  public static class UserStorage
  {
    public static List<User> Users { get; set; } = new List<User> {
      new User {ID=Guid.NewGuid(),Username="user1",Password = "user1psd" },
      new User {ID=Guid.NewGuid(),Username="user2",Password = "user2psd" },
      new User {ID=Guid.NewGuid(),Username="user3",Password = "user3psd" }
    };
  }
}

4.2Angular2端

4.2.1創(chuàng)建View Model

在wwwroot/app下創(chuàng)建一個(gè)目錄:_model, 并添加一個(gè)Typescript文件RequestResult.ts,內(nèi)容應(yīng)該是這樣。

export class RequestResult {
  State: number;
  Msg: string;
  Data: Object;
}

4.2.2創(chuàng)建Service

在wwwroot/app下創(chuàng)建一個(gè)目錄:_services,并添加一個(gè)Typescript文件auth.service.ts,內(nèi)容應(yīng)該是這樣。

import { Injectable } from "@angular/core";
import { Headers, Http } from "@angular/http";
import "rxjs/add/operator/toPromise";

import { RequestResult } from "../_model/RequestResult";

@Injectable()
export class AuthService {
  private tokeyKey = "token";
  private token: string;

  constructor(
    private http: Http
  ) { }

  login(userName: string, password: string): Promise<RequestResult> {
    return this.http.post("/api/TokenAuth", { Username: userName, Password: password }).toPromise()
      .then(response => {
        let result = response.json() as RequestResult;
        if (result.State == 1) {
          let json = result.Data as any;

          sessionStorage.setItem("token", json.accessToken);
        }
        return result;
      })
      .catch(this.handleError);
  }

  checkLogin(): boolean {
    var token = sessionStorage.getItem(this.tokeyKey);
    return token != null;
  }

  getUserInfo(): Promise<RequestResult> {
    return this.authGet("/api/TokenAuth");
  }

  authPost(url: string, body: any): Promise<RequestResult> {
    let headers = this.initAuthHeaders();
    return this.http.post(url, body, { headers: headers }).toPromise()
      .then(response => response.json() as RequestResult)
      .catch(this.handleError);
  }

  authGet(url): Promise<RequestResult> {
    let headers = this.initAuthHeaders();
    return this.http.get(url, { headers: headers }).toPromise()
      .then(response => response.json() as RequestResult)
      .catch(this.handleError);
  }

  private getLocalToken(): string {
    if (!this.token) {
      this.token = sessionStorage.getItem(this.tokeyKey);
    }
    return this.token;
  }

  private initAuthHeaders(): Headers {
    let token = this.getLocalToken();
    if (token == null) throw "No token";

    var headers = new Headers();
    headers.append("Authorization", "Bearer " + token);

    return headers;
  }

  private handleError(error: any): Promise<any> {
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
  }
}

本文件主要用來(lái)完成登錄以及登錄驗(yàn)證工作,之后該service將可以被注入到Component中以便被Component調(diào)用。

注:主要的邏輯都應(yīng)該寫(xiě)到service中

4.2.3.創(chuàng)建Component

4.2.3.1.在wwwroot/app下創(chuàng)建一個(gè)目錄home,該目錄用來(lái)存放HomeComponent,home應(yīng)擁有如下文件:

?home.component.ts

import { Component, OnInit } from "@angular/core";

import { AuthService } from "../_services/auth.service";

@Component({
  moduleId: module.id,
  selector: "my-home",
  templateUrl: "view.html",
  styleUrls: ["style.css"]
})
export class HomeComponent implements OnInit {
  isLogin = false;
  userName: string;
  
  constructor(
    private authService: AuthService
  ) { }

  ngOnInit(): void {
    this.isLogin = this.authService.checkLogin();
    if (this.isLogin) {
      this.authService.getUserInfo().then(res => {
        this.userName = (res.Data as any).UserName;
      });
    }

  }
}

查閱代碼,在@Component中指定了View以及style。

AuthService被在構(gòu)造方法中被注入了本Component,ngOnInit是接口OnInit的一個(gè)方法,他在Component初始化時(shí)會(huì)被調(diào)用。

?style.css

/*styles of this view*/

本例中沒(méi)有添加任何樣式,如有需要可以寫(xiě)在這里。

?view.html

<div *ngIf="isLogin">
  <h2>Hi <span>{{userName}}</span></h2>
</div>

<div *ngIf="!isLogin">
  <h2>please login</h2>
  <a routerLink="/login">Login</a>
</div>

*ngIf=""是Angular2 的其中一種標(biāo)記語(yǔ)法,作用是當(dāng)返回真時(shí)渲染該節(jié)點(diǎn),完整教程請(qǐng)參閱官方文檔。

4.2.3.2.在wwwroot/app下創(chuàng)建目錄Login,該目錄用來(lái)存放LoginComponent,文件結(jié)構(gòu)類似于上一節(jié)。

?login.component.ts

import { Component } from "@angular/core";
import { Router } from '@angular/router';

import { AuthService } from "../_services/auth.service";

@Component({
  moduleId: module.id,
  selector: "my-login",
  templateUrl: "view.html",
  styleUrls: ["style.css"]
})
export class LoginComponent {

  private userName: string;
  private password: string;

  constructor(
    private authService: AuthService,
    private router: Router
  ) { }

  login() {
    this.authService.login(this.userName, this.password)
      .then(result => {
        if (result.State == 1) {
          this.router.navigate(["./home"]);
        }
        else {
          alert(result.Msg);
        }
      });
  }
}

?style.css

/*styles of this view*/

?view.html

<table>
  <tr>
    <td>userName:</td>
    <td><input [(ngModel)]="userName" placeholder="useName:try type user1" /></td>
  </tr>
  <tr>
    <td>userName:</td>
    <td><input [(ngModel)]="password" placeholder="password:try type user1psd" /></td>
  </tr>
  <tr>
    <td></td>
    <td><input type="button" (click)="login()" value="Login" /></td>
  </tr>
</table>

4.2.4.應(yīng)用路由

路由是切換多頁(yè)面用的。

在wwwroot/app下新建一個(gè)Typescript文件,命名為app-routing.module.ts,內(nèi)容應(yīng)該是這個(gè)樣子。

import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";

import { HomeComponent } from "./home/home.component";
import { LoginComponent } from "./login/login.component"

const routes: Routes = [
  { path: "", redirectTo: "/home", pathMatch: "full" },
  { path: "home", component: HomeComponent },
  { path: "login", component: LoginComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

接下來(lái)我們來(lái)應(yīng)用這個(gè)路由,

打開(kāi)app.module.ts,更新代碼如下:

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { HttpModule } from "@angular/http";
import { FormsModule } from "@angular/forms";

import { AppRoutingModule } from "./app-routing.module";

import { AuthService } from "./_services/auth.service";

import { AppComponent } from "./app.component";
import { HomeComponent } from "./home/home.component";
import { LoginComponent } from "./login/login.component";

@NgModule({
  bootstrap: [AppComponent],
  imports: [
    BrowserModule,
    HttpModule,
    AppRoutingModule,
    FormsModule
  ],
  declarations: [
    AppComponent,
    HomeComponent,
    LoginComponent
  ],
  providers: [AuthService]
})
export class AppModule { }

NgModule和BrowserModule你可以理解為基礎(chǔ)模塊,必加的。

HttpModule是做http請(qǐng)求用的。

FormsModule是做雙向數(shù)據(jù)綁定用的,比如下面這樣的,如果想把數(shù)據(jù)從view更新到component,就必須加這個(gè)。

<input [(ngModel)]="userName" placeholder="useName:try type user1" />

AppRoutingModule即為我們剛才添加的路由文件。

AuthService是我們最早添加的service文件。

AppComponent是我們最初添加的那個(gè)app.component.ts里的那個(gè)component.

HomeComponent,LoginComponent同上。

最后我們?cè)賏pp.component.ts中添加路由錨點(diǎn),

把template的值為 "<router-outlet></router-outlet>"

完整的代碼應(yīng)該是這樣:

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'my-app',
  template: "<router-outlet></router-outlet>",
})
export class AppComponent {
}

router-outlet是路由錨點(diǎn)的關(guān)鍵詞。

感謝各位的閱讀!關(guān)于“ASP.NET Core中如何使用Angular2”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI