angular 部署_如何使用Angular 5和Entity Framework Core在HTML中部署可编辑表

董高畅
2023-12-01

angular 部署

介绍 (Introduction)

In this article, we are going to create a web application using ASP.NET Core 2.0 and Angular 5 with the help of the Entity Framework (EF) Core database-first approach. We will be creating a sample Employee Record Management system. To read the inputs from the user, we will use Angular forms with required field validations on the client side. We are also going to bind a dropdown list in the Angular form to a table in the database using EF Core.

在本文中,我们将借助实体框架(EF)核心数据库优先方法,使用ASP.NET Core 2.0Angular 5创建一个Web应用程序。 我们将创建一个示例员工记录管理系统。 为了从用户那里读取输入,我们将在客户端使用Angular表单以及必需的字段验证。 我们还将使用EF Core将Angular形式的下拉列表绑定到数据库中的表。

We will be using Visual Studio 2017 and SQL Server version 2008 or above.

我们将使用Visual Studio 2017SQL Server 2008或更高版本。

先决条件 (Prerequisites)

  • Install .NET Core 2.0.0 or above SDK from here.

    此处安装.NET Core 2.0.0或更高版本的SDK。

  • Install the latest version of Visual Studio 2017 Community Edition from here.

    此处安装最新版本的Visual Studio 2017社区版。

  • Download and install the latest version of Node.js from here..

    此处下载并安装最新版本的Node.js。

  • SQL Server 2008 or above.

    SQL Server 2008或更高版本。

源代码 (Source Code)

Before proceeding, I recommend you get the source code from Github.

在继续之前,建议您从Github获取源代码。

创建表 (Creating the tables)

We will be using two tables to store our data.

我们将使用两个表来存储我们的数据。

  1. tblEmployee: used to store the details of employees. It contains fields such as EmployeeID, Name, City, Department, and Gender.

    tblEmployee :用于存储员工的详细信息。 它包含诸如EmployeeID,姓名,城市,部门和性别之类的字段。

  2. tblCities: this contains the list of cities. It is used to populate the City field of the tblEmployee table. tblCities contains two fields, CityID and CityName.

    tblCities :这包含城市列表。 它用于填充tblEmployee表的City字段。 tblCities包含两个字段,CityID和CityName。

Execute the following commands to create both tables:

执行以下命令来创建两个表:

CREATE TABLE tblEmployee (  EmployeeID int IDENTITY(1,1) NOT NULL PRIMARY KEY,  Name varchar(20) NOT NULL ,  City varchar(20) NOT NULL ,  Department varchar(20) NOT NULL ,  Gender varchar(6) NOT NULL   )  GO    CREATE TABLE tblCities (  CityID int IDENTITY(1,1) NOT NULL PRIMARY KEY,  CityName varchar(20) NOT NULL   )  GO

Now we will put some data into the tblCities table. We will be using this table to bind a dropdown list in our web application. The desired city can be selected using this dropdown list. Use the following insert statements.

现在,我们将一些数据放入tblCities表中。 我们将使用此表来绑定Web应用程序中的下拉列表。 可以使用此下拉列表选择所需的城市。 使用以下插入语句。

INSERT INTO tblCities VALUES('New Delhi');  INSERT INTO tblCities VALUES('Mumbai');  INSERT INTO tblCities VALUES('Hyderabad');  INSERT INTO tblCities VALUES('Chennai');  INSERT INTO tblCities VALUES('Bengaluru');

Now, our Database part has been completed. So, we will proceed to create the MVC application using Visual Studio 2017.

现在,我们的数据库部分已经完成。 因此,我们将继续使用Visual Studio 2017创建MVC应用程序。

创建ASP.NET MVC Web应用程序 (Create the ASP.NET MVC web application)

Open Visual Studio and select File >> New >> Project.

打开Visual Studio,然后选择“文件>>新建>>项目”。

After selecting the project, a “New Project” dialog will open. Select .NET Core inside Visual C# menu from the left panel.

选择项目后,将打开“新建项目”对话框。 从左侧面板的Visual C#菜单中选择.NET Core。

Then, select “ASP.NET Core Web Application” from the available project types. Put the name of the project as “EFNgApp” and press OK.

然后,从可用的项目类型中选择“ ASP.NET Core Web应用程序”。 将项目名称命名为“ EFNgApp” 然后按确定。

After clicking on OK, a new dialog will open asking you to select the project template. You can observe two drop-down menus at the top left of the template window. Select “.NET Core” and “ASP.NET Core 2.0” from these dropdowns. Then, select the “Angular” template and press OK.

单击确定后,将打开一个新对话框,要求您选择项目模板。 您可以在模板窗口的左上方观察两个下拉菜单。 从这些下拉列表中选择“ .NET Core”和“ ASP.NET Core 2.0”。 然后,选择“ Angular”模板,然后按OK。

Now, our project will be created. You can see the folder structure in Solution Explorer in the below image.

现在,将创建我们的项目。 您可以在下图中的解决方案资源管理器中看到文件夹结构。

Here, we have our “Controllers” and “Views” folders. We won’t be touching the Views folder for this tutorial, since we will be using Angular to handle the UI.

在这里,我们有“ Controllers”和“ Views”文件夹。 本教程不会涉及Views文件夹,因为我们将使用Angular来处理UI。

The Controllers folders will contain our Web API controller. The point of interest for us is the “ClientApp” folder where the client side of our application resides.

Controllers文件夹将包含我们的Web API控制器。 我们感兴趣的是应用程序客户端所在的“ ClientApp”文件夹。

Inside the “ClientApp/app/components folder,” we already have few components created. These are provided by default with the Angular template in VS 2017. These components won’t affect our application, but for the sake of this tutorial, we will delete the “fetchdata” and “counter” folders from ClientApp/app/components.

在“ ClientApp / app / components文件夹”内,我们已经创建了几个组件。 VS 2017中的Angular模板默认提供这些组件。这些组件不会影响我们的应用程序,但是出于本教程的考虑,我们将从ClientApp / app / components中删除“ fetchdata”和“ counter”文件夹

将模型添加到应用程序 (Adding the Model to the Application)

We are using Entity Framework core database first approach to create our models. Navigate to Tools >> NuGet Package Manager >> Package Manager Console.

我们正在使用Entity Framework核心数据库优先方法来创建模型。 导航到工具>> NuGet软件包管理器>>软件包管理器控制台。

We have to install the package for the database provider that we are targeting, which is SQL Server in this case. Now run the following command:

我们必须为目标数据库提供程序安装软件包,在这种情况下为SQL Server。 现在运行以下命令:

Install-Package Microsoft.EntityFrameworkCore.SqlServer

Since we are using Entity Framework Tools to create a model from the existing database, we will install the tools package as well. Run the following command:

由于我们使用实体框架工具从现有数据库创建模型,因此我们还将安装工具包。 运行以下命令:

Install-Package Microsoft.EntityFrameworkCore.Tools

After you have installed both the packages, we will scaffold our model from the database tables using the following command:

在安装完两个软件包之后,我们将使用以下命令从数据库表中构建模型:

Scaffold-DbContext "Your connection string here" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables tblEmployee, tblCities

Do not forget to put your own connection string (inside double quotes “ ”). After this command gets executed successfully, a “Models” folder will be created. This folder contains three class files: myTestDBContext.cs, TblCities.cs and TblEmployee.cs. We have successfully created our Models using EF core database first approach.

不要忘记在连接字符串中加上双引号“”。 成功执行此命令后,将创建一个“模型”文件夹。 此文件夹包含三个类文件: myTestDBContext.cs TblCities.cs TblEmployee.cs 。 我们已经使用EF核心数据库优先方法成功创建了模型。

Now, we will create one more class file to handle database related operations

现在,我们将再创建一个类文件来处理与数据库相关的操作

Right click on the “Models” folder and select Add >> Class. Name your class EmployeeDataAccessLayer.cs and click the “Add” button. At this point, the “Models” folder will have the following structure.

右键单击“模型”文件夹,然后选择添加>>类。 将您的class EmployeeDataAccessLa命名为class EmployeeDataAccessLa y er.cs,然后单击“添加”按钮。 此时,“模型”文件夹将具有以下结构。

Open “EmployeeDataAccessLayer.cs” and insert the following code to handle database operations.

打开“ EmployeeDataAccessLayer.cs” 并插入以下代码来处理数据库操作。

using Microsoft.EntityFrameworkCore;  using System;  using System.Collections.Generic;  using System.Linq;  using System.Threading.Tasks;    namespace EFNgApp.Models  {      public class EmployeeDataAccessLayer      {          myTestDBContext db = new myTestDBContext();            public IEnumerable<TblEmployee> GetAllEmployees()          {              try              {                  return db.TblEmployee.ToList();              }              catch              {                  throw;              }          }            //To Add new employee record           public int AddEmployee(TblEmployee employee)          {              try              {                  db.TblEmployee.Add(employee);                  db.SaveChanges();                  return 1;              }              catch              {                  throw;              }          }            //To Update the records of a particluar employee          public int UpdateEmployee(TblEmployee employee)          {              try              {                  db.Entry(employee).State = EntityState.Modified;                  db.SaveChanges();                    return 1;              }              catch              {                  throw;              }          }            //Get the details of a particular employee          public TblEmployee GetEmployeeData(int id)          {              try              {                  TblEmployee employee = db.TblEmployee.Find(id);                  return employee;              }              catch              {                  throw;              }          }            //To Delete the record of a particular employee          public int DeleteEmployee(int id)          {              try              {                  TblEmployee emp = db.TblEmployee.Find(id);                  db.TblEmployee.Remove(emp);                  db.SaveChanges();                  return 1;              }              catch              {                  throw;              }          }            //To Get the list of Cities          public List<TblCities> GetCities()          {              List<TblCities> lstCity = new List<TblCities>();              lstCity = (from CityList in db.TblCities select CityList).ToList();                return lstCity;          }      }  }

Now, we will proceed to create our Web API Controller.

现在,我们将继续创建Web API控制器。

将Web API控制器添加到应用程序 (Adding the Web API Controller to the Application)

Right click on Controllers folder and select Add >> New Item.

右键单击Controllers文件夹,然后选择Add >> New Item。

An “Add New Item” dialog box will open. Select “ASP.NET from the left panel. Then, select “Web API Controller Class” from templates panel and put the name as EmployeeController.cs. Click “Add”.

“添加新项”对话框将打开。 从左侧面板中选择“ ASP.NET 。 然后,从模板面板中选择“ Web API Controller Class”,并将名称命名为EmployeeController.cs 。 点击“添加”。

This will create our Web API “EmployeeController” class. We will put all our business logic in this controller. We will call the methods of “EmployeeDataAccessLayer” to fetch data and pass on the data to the Angular frontend.

这将创建我们的Web API“ EmployeeController” 类。 我们将所有业务逻辑放入此控制器中。 我们将调用“ EmployeeDataAccessLayer”方法 获取数据并将数据传递到Angular前端。

Open the “EmployeeController.cs” file and insert the following code into it:

打开“ EmployeeController.cs” 文件并将以下代码插入其中:

using System;  using System.Collections.Generic;  using System.Linq;  using System.Threading.Tasks;  using EFNgApp.Models;  using Microsoft.AspNetCore.Mvc;     namespace EFNgApp.Controllers  {        public class EmployeeController : Controller      {          EmployeeDataAccessLayer objemployee = new EmployeeDataAccessLayer();            [HttpGet]          [Route("api/Employee/Index")]          public IEnumerable<TblEmployee> Index()          {              return objemployee.GetAllEmployees();          }            [HttpPost]          [Route("api/Employee/Create")]          public int Create([FromBody] TblEmployee employee)          {              return objemployee.AddEmployee(employee);          }            [HttpGet]          [Route("api/Employee/Details/{id}")]          public TblEmployee Details(int id)          {              return objemployee.GetEmployeeData(id);          }            [HttpPut]          [Route("api/Employee/Edit")]          public int Edit([FromBody]TblEmployee employee)          {              return objemployee.UpdateEmployee(employee);          }            [HttpDelete]          [Route("api/Employee/Delete/{id}")]          public int Delete(int id)          {              return objemployee.DeleteEmployee(id);          }            [HttpGet]          [Route("api/Employee/GetCityList")]          public IEnumerable<TblCities> Details()          {              return objemployee.GetCities();          }      }  }

We are done with our backend logic. Now we’ll code our frontend using Angular 5.

我们已经完成了后端逻辑。 现在,我们将使用Angular 5编写前端代码。

创建角度服务 (Create the Angular Service)

We will create an Angular service which will convert the Web API response to JSON and pass it to our component.

我们将创建一个Angular服务,它将Web API响应转换为JSON并将其传递给我们的组件。

Right-click on the “ClientApp/app” folder and then Add >> New Folder and name the folder as “Services”.

右键单击“ ClientApp / app”文件夹,然后单击添加>>新建文件夹,并将该文件夹命名为“服务”。

Right-click on the “Services” folder and select Add >> New Item. An “Add New Item” dialog box will open. Select “Scripts” from the left panel. Then select “TypeScript File” from the templates panel, and put the name as empservice.service.ts. Click “Add”.

右键单击“服务”文件夹,然后选择“添加>>新建项目”。 “添加新项”对话框将打开。 从左侧面板中选择“脚本”。 然后从模板面板中选择“ TypeScript File”,并将其me as empservice.serv empservice.service.ts。 点击“添加”。

Open the “empservice.service.ts” file and insert the following code into it:

打开“ empservice.service.ts”文件,并将以下代码插入其中:

import { Injectable, Inject } from '@angular/core';  import { Http, Response } from '@angular/http';  import { Observable } from 'rxjs/Observable';  import { Router } from '@angular/router';  import 'rxjs/add/operator/map';  import 'rxjs/add/operator/catch';  import 'rxjs/add/observable/throw';    @Injectable()  export class EmployeeService {      myAppUrl: string = "";        constructor(private _http: Http, @Inject('BASE_URL') baseUrl: string) {          this.myAppUrl = baseUrl;      }        getCityList() {          return this._http.get(this.myAppUrl + 'api/Employee/GetCityList')              .map(res => res.json())              .catch(this.errorHandler);      }        getEmployees() {          return this._http.get(this.myAppUrl + 'api/Employee/Index')              .map((response: Response) => response.json())              .catch(this.errorHandler);      }        getEmployeeById(id: number) {          return this._http.get(this.myAppUrl + "api/Employee/Details/" + id)              .map((response: Response) => response.json())              .catch(this.errorHandler)      }        saveEmployee(employee) {          return this._http.post(this.myAppUrl + 'api/Employee/Create', employee)              .map((response: Response) => response.json())              .catch(this.errorHandler)      }        updateEmployee(employee) {          return this._http.put(this.myAppUrl + 'api/Employee/Edit', employee)              .map((response: Response) => response.json())              .catch(this.errorHandler);      }        deleteEmployee(id) {          return this._http.delete(this.myAppUrl + "api/Employee/Delete/" + id)              .map((response: Response) => response.json())              .catch(this.errorHandler);      }        errorHandler(error: Response) {          console.log(error);          return Observable.throw(error);      }  }

At this point, you might get the following error: “Parameter ‘employee’ implicitly has an ‘any’ type” in “empservice.service.ts” file.

此时,您可能会收到以下错误:“ empservice.service.ts”中的“参数'employee'隐式具有'any'类型” 文件。

If you encounter this issue, then add the following line inside the “tsconfig.json” file.

如果遇到此问题,请在“ tsconfig.json”文件中添加以下行。

“noImplicitAny”: false

“ noImplicitAny”:否

Now, we will create our components.

现在,我们将创建我们的组件。

创建角度组件 (Creating Angular components)

We will be adding two Angular components to our application:

我们将在我们的应用程序中添加两个Angular组件:

  1. fetchemployee component: to display all the employee data or delete existing employee data.

    fetchemployee组件:显示所有员工数据或删除现有员工数据。

  2. addemployee component: to add a new employee data or edit an existing employee data.

    addemployee组件:添加新员工数据或编辑现有员工数据。

Right-click on the “ClientApp/app/components” folder and select Add >> New Folder and name the folder “addemployee”.

右键点击“ ClientApp / app / components” 文件夹,然后选择添加>>新建文件夹,并将文件夹命名为“ addem p loyee”。

Right-click on the “addemployee” folder, and select Add >> New Item. An “Add New Item” dialog box will open.

右键单击“ addemployee” 文件夹,然后选择添加>>新建项目。 “添加新项”对话框将打开。

Select “Scripts from the left panel, then select “TypeScript File” from templates panel. Put the name as addemployee.component.ts.

从左侧面板中选择“脚本 ,然后从模板面板中选择“ TypeScript文件”。 将名称命名为addemployee.component.ts

Click “Add”. This will add a typescript file inside the “addemployee” folder.

点击“添加”。 这将在“ addemployee”内部添加一个打字稿文件 夹。

Right-click on the “addemployee” folder and select Add >> New Item. An “Add New Item” dialog box will open.

右键单击“ addemployee” 文件夹,然后选择添加>>新建项目。 “添加新项”对话框将打开。

Select “ASP.NET Core from the left panel, then select “HTML Page” from templates panel. Put the name as addemployee.component.html.

从左侧面板中选择“ ASP.NET Core ,然后从模板面板中选择“ HTML页面”。 将名称命名为addemployee.component.html

Click “Add”. This will add a HTML file inside the “addemployee” folder.

点击“添加”。 这将在“ addemployee”内部添加一个HTML文件。 夹。

Similarly, create a “fetchemployee” folder inside the “ClientApp/app/components” folder.

同样,在“ ClientApp / app / components”内部创建一个“ fetchemployee”文件夹 夹。

Add fetchemployee.component.ts and fetchemployee.component.html files to it.

向其中添加fetchemployee.component.tsfetchemployee.component.html文件。

Now our “ClientApp/app/components” structure will look like the image below.

现在我们的“ ClientApp / app / components” 结构如下图所示。

Open fetchemployee.component.ts and insert the following code:

打开fetchemployee.component.ts 并插入以下代码:

import { Component, Inject } from '@angular/core';  import { Http, Headers } from '@angular/http';  import { Router, ActivatedRoute } from '@angular/router';  import { EmployeeService } from '../../services/empservice.service'    @Component({      templateUrl: './fetchemployee.component.html'  })    export class FetchEmployeeComponent {      public empList: EmployeeData[];        constructor(public http: Http, private _router: Router, private _employeeService: EmployeeService) {          this.getEmployees();      }        getEmployees() {          this._employeeService.getEmployees().subscribe(              data => this.empList = data          )      }        delete(employeeID) {          var ans = confirm("Do you want to delete customer with Id: " + employeeID);          if (ans) {              this._employeeService.deleteEmployee(employeeID).subscribe((data) => {                  this.getEmployees();              }, error => console.error(error))          }      }  }    interface EmployeeData {      employeeId: number;      name: string;      gender: string;      city: string;      department: string;    }

Let’s understand this code.

让我们了解这段代码。

At the very top we have imported Angular modules and EmployeeService references. After this we use @Component decorator to define the template URL for our component.

在最顶部,我们导入了Angular模块和EmployeeService引用。 之后,我们使用@Component装饰器定义组件的模板URL。

Inside the FetchEmployeeComponent class we have declared an array variable empList of type EmployeeData. EmployeeData is an interface having the properties same as our TblEmployeeModel class.

FetchEmployeeComponent类内部,我们声明了一个类型为EmployeeData的数组变量empList EmployeeData是一个接口,其属性与我们的TblEmployeeModel类相同。

Inside the getEmployees method we are calling the getEmployees method of our service EmployeeService. This will return an array of Employees to be stored in the empList variable. The getEmployees method is called inside the constructor, so that the employee data will be displayed as the page loads.

getEmployees内部 我们正在调用服务EmployeeServicegetEmployees方法的方法。 这将返回一个Employees数组,将其存储在empList变量中。 在构造函数内部调用getEmployees方法,以便在页面加载时显示雇员数据。

Next, we have a delete method which accepts employeeID as a parameter. This will prompt the user with a confirmation box. If the user selects “yes” then it will delete the employee with this employeeID.

接下来,我们有一个delete方法,它接受employeeID作为参数。 这将提示用户确认框。 如果用户选择“是”,则它将删除具有此employeeID的员工。

Open fetchemployee.component.html and insert the following code:

打开fetchemployee.component.html 并插入以下代码:

<h1>Employee Data</h1>    <p>This component demonstrates fetching Employee data from the server.</p>    <p *ngIf="!empList"><em>Loading...</em></p>    <p>      <a [routerLink]="['/register-employee']">Create New</a>  </p>    <table class='table' *ngIf="empList">      <thead>          <tr>              <th>EmployeeId</th>              <th>Name</th>              <th>Gender</th>              <th>Department</th>              <th>City</th>          </tr>      </thead>      <tbody>          <tr *ngFor="let emp of empList">              <td>{{ emp.employeeId }}</td>              <td>{{ emp.name }}</td>              <td>{{ emp.gender }}</td>              <td>{{ emp.department }}</td>              <td>{{ emp.city }}</td>              <td>              <td>                  <a [routerLink]="['/employee/edit/', emp.employeeId]">Edit</a> |                  <a [routerLink]="" (click)="delete(emp.employeeId)">Delete</a>              </td>          </tr>      </tbody>  </table>

The code for this HTML file is pretty simple.

该HTML文件的代码非常简单。

At the top it has a link to create new employee record. After that it has a table to display employee data, and two links for editing and deleting each employee record.

顶部具有创建新员工记录的链接。 之后,它具有一个用于显示员工数据的表以及两个用于编辑和删除每个员工记录的链接。

We are finished with our fetchemployee component.

我们完成了fetchemployee组件。

Now open addemployee.component.ts and insert the following code.

现在打开addemployee.component.ts 并插入以下代码。

import { Component, OnInit } from '@angular/core';  import { Http, Headers } from '@angular/http';  import { NgForm, FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';  import { Router, ActivatedRoute } from '@angular/router';  import { FetchEmployeeComponent } from '../fetchemployee/fetchemployee.component';  import { EmployeeService } from '../../services/empservice.service';    @Component({      templateUrl: './AddEmployee.component.html'  })    export class createemployee implements OnInit {      employeeForm: FormGroup;      title: string = "Create";      employeeId: number;      errorMessage: any;      cityList: Array<any> = [];        constructor(private _fb: FormBuilder, private _avRoute: ActivatedRoute,          private _employeeService: EmployeeService, private _router: Router) {          if (this._avRoute.snapshot.params["id"]) {              this.employeeId = this._avRoute.snapshot.params["id"];          }            this.employeeForm = this._fb.group({              employeeId: 0,              name: ['', [Validators.required]],              gender: ['', [Validators.required]],              department: ['', [Validators.required]],              city: ['', [Validators.required]]          })      }        ngOnInit() {            this._employeeService.getCityList().subscribe(              data => this.cityList = data          )            if (this.employeeId > 0) {              this.title = "Edit";              this._employeeService.getEmployeeById(this.employeeId)                  .subscribe(resp => this.employeeForm.setValue(resp)                  , error => this.errorMessage = error);          }        }        save() {            if (!this.employeeForm.valid) {              return;          }            if (this.title == "Create") {              this._employeeService.saveEmployee(this.employeeForm.value)                  .subscribe((data) => {                      this._router.navigate(['/fetch-employee']);                  }, error => this.errorMessage = error)          }          else if (this.title == "Edit") {              this._employeeService.updateEmployee(this.employeeForm.value)                  .subscribe((data) => {                      this._router.navigate(['/fetch-employee']);                  }, error => this.errorMessage = error)          }      }        cancel() {          this._router.navigate(['/fetch-employee']);      }        get name() { return this.employeeForm.get('name'); }      get gender() { return this.employeeForm.get('gender'); }      get department() { return this.employeeForm.get('department'); }      get city() { return this.employeeForm.get('city'); }  }

This component will be used for both adding and editing the employee data.

此组件将用于添加和编辑员工数据。

Since we are using a form model, along with client-side validation to add and edit employee data, we have imported classes from @angular/forms. The code to create the form has been put inside the constructor so that the form will be displayed as the page loads.

由于我们使用表单模型以及客户端验证来添加和编辑员工数据,因此我们从@ angular / forms中导入了类。 创建表单的代码已放入构造函数中,以便在页面加载时显示表单。

This component will handle both add and edit requests. So how will the system differentiate between both requests? The answer is routing. We need to define two different route parameters. One is for adding employee records. The other is for editing employee records. These route parameters will be defined in app.shared.module.ts in the following section.

该组件将处理添加和编辑请求。 那么系统将如何区分这两个请求? 答案是路由。 我们需要定义两个不同的路由参数。 一种是添加员工记录。 另一个用于编辑员工记录。 这些路由参数将在app.shared.module.ts中定义。

We have declared the variable title to show on the top of the page and variable id to store the employee id passed as the parameter in case of an edit request. To read the employee ID from the URL we will use ActivatedRoute.snapshot inside the constructor, and set the value of variable id.

我们声明了变量title显示在页面顶部,并声明了变量id以存储在进行编辑请求时作为参数传递的员工ID。 要从URL读取员工ID,我们将在构造函数中使用ActivatedRoute.snapshot ,并设置变量id的值。

Inside ngOnInit we are performing two operations:

ngOnInit内部,我们执行两个操作:

  1. We are fetching the list of cities by calling the getCityList method from our service. We will bind the list of cities to a dropdown list in our HTML page. Since we are calling the getCityList method in ngOnInit, the dropdown list will be populated as the page loads.

    我们正在通过从服务中调用getCityList方法来获取城市列表。 我们会将城市列表绑定到HTML页面中的下拉列表。 由于我们在getCityList中调用getCityList方法, ngOnInit将在页面加载时填充下拉列表。

  2. We will check if the id is set then we will change the title to “Edit”, get the data for that id from our service, and populate the fields in our form. The value read from the database will be returned as JSON. It will have all the same properties as we declared in our FormBuilder, hence we use the setValue method to populate our form.

    我们将检查id是否已设置,然后将标题更改为“编辑”,从服务中获取该id的数据,然后在表单中填充字段。 从数据库读取的值将作为JSON返回。 它具有与在FormBuilder声明的所有属性相同的属性,因此我们使用setValue方法填充表单。

The save method will be called when the “Save” button of our form is clicked. The add and edit operations will call the corresponding method from our service and then, upon success, redirect back to the fetch-employee component.

单击表单的“保存”按钮时,将调用save方法。 添加编辑操作将从我们的服务中调用相应的方法,然后在成功后将其重定向回fetch-employee组件。

In the last one we have also defined getter functions for the control names of our form to enable client-side validation.

在上一个中,我们还为表单的控件名称定义了getter函数,以启用客户端验证。

Open addemployee.component.html and insert the following code.

打开addemployee.component.html 并插入以下代码。

<!DOCTYPE html>  <html>  <head>      <meta charset="utf-8" />      <title></title>  </head>  <body>        <h1>{{title}}</h1>      <h3>Employee</h3>      <hr />      <form [formGroup]="employeeForm" (ngSubmit)="save()" #formDir="ngForm" novalidate>            <div class="form-group row">              <label class=" control-label col-md-12" for="Name">Name</label>              <div class="col-md-4">                  <input class="form-control" type="text" formControlName="name">              </div>              <span class="text-danger" *ngIf="employeeForm.hasError('required', 'name') && formDir.submitted">                  Name is required.              </span>          </div>          <div class="form-group row">              <label class="control-label col-md-12" for="Gender">Gender</label>              <div class="col-md-4">                  <select class="form-control" data-val="true" formControlName="gender">                      <option value="">-- Select Gender --</option>                      <option value="Male">Male</option>                      <option value="Female">Female</option>                  </select>              </div>              <span class="text-danger" *ngIf="employeeForm.hasError('required', 'gender') && formDir.submitted">                  Gender is required              </span>          </div>          <div class="form-group row">              <label class="control-label col-md-12" for="Department">Department</label>              <div class="col-md-4">                  <input class="form-control" type="text" formControlName="department">              </div>              <span class="text-danger" *ngIf="employeeForm.hasError('required', 'department') && formDir.submitted">                  Department is required              </span>          </div>          <div class="form-group row">              <label class="control-label col-md-12" for="City">City</label>              <div class="col-md-4">                  <select class="form-control" data-val="true" formControlName="city">                      <option value="">--Select City--</option>                      <option *ngFor="let city of cityList"                              value={{city.cityName}}>                          {{city.cityName}}                      </option>                  </select>              </div>              <span class="text-danger" *ngIf="employeeForm.hasError('required', 'city') && formDir.submitted">                  City is required              </span>          </div>          <div class="form-group">              <button type="submit" class="btn btn-default">Save</button>              <button class="btn" (click)="cancel()">Cancel</button>          </div>      </form>  </body>  </html>

Here you can observe that we have attribute [formGroup]=“employeeForm”, which is our defined form group name in addemployee.component.ts. (ngSubmit)=“save()” will invoke our save method on form submit.

在这里,您可以看到我们具有属性[formGroup]=“employeeForm” ,这是我们在addemployee.component.ts定义的表单组名称。 (ngSubmit)=“save()”将在表单提交时调用我们的save方法。

Also, every input control has attribute formControlName=“xyz”. This is used to bind FormControl to HTML. We have also defined error messages for client-side validation checks. These will be invoked on form submission only.

同样,每个输入控件都具有formControlName=“xyz”属性。 这用于将FormControl绑定到HTML。 我们还为客户端验证检查定义了错误消息。 这些仅在表单提交时被调用。

For binding the dropdown list we are using the cityList property that we have populated from tblCities. It was populated by calling the getCityList method from our service, inside the ngOnInit method of addemployee.component.ts.

为了绑定下拉列表,我们使用从tblCities填充的cityList属性。 它是通过在getCityList方法内从我们的服务中调用ngOnInit方法来addemployee.component.ts

为我们的应用程序定义路线和导航菜单 (Defining the route and navigation menu for our Application)

Inside the “app” folder, open app.shared.module.ts and insert the following code:

在“ app”文件夹中,打开app.shared.module.ts 并插入以下代码:

import { NgModule } from '@angular/core';  import { EmployeeService } from './services/empservice.service'  import { CommonModule } from '@angular/common';  import { FormsModule, ReactiveFormsModule } from '@angular/forms';  import { HttpModule } from '@angular/http';  import { RouterModule } from '@angular/router';    import { AppComponent } from './components/app/app.component';  import { NavMenuComponent } from './components/navmenu/navmenu.component';  import { HomeComponent } from './components/home/home.component';  import { FetchEmployeeComponent } from './components/fetchemployee/fetchemployee.component'  import { createemployee } from './components/addemployee/AddEmployee.component'    @NgModule({      declarations: [          AppComponent,          NavMenuComponent,          HomeComponent,          FetchEmployeeComponent,          createemployee,      ],      imports: [          CommonModule,          HttpModule,          FormsModule,          ReactiveFormsModule,          RouterModule.forRoot([              { path: '', redirectTo: 'home', pathMatch: 'full' },              { path: 'home', component: HomeComponent },              { path: 'fetch-employee', component: FetchEmployeeComponent },              { path: 'register-employee', component: createemployee },              { path: 'employee/edit/:id', component: createemployee },              { path: '**', redirectTo: 'home' }          ])      ],      providers: [EmployeeService]  })  export class AppModuleShared {  }

Here we have also imported all our components and defined the route for our application as below:

在这里,我们还导入了所有组件,并为我们的应用程序定义了路由,如下所示:

  • home: which will redirect to the home component

    home:它将重定向到home组件

  • fetch-employee: to display all employee data using the fetchemployeecomponent

    fetch-employee:使用fetchemployee组件显示所有员工数据

  • register-employee: to add new employee record using the createemployeecomponent

    register-employee:使用createemployee组件添加新员工记录

  • employee/edit/:id: to edit existing employee record using the createemployee component

    employee / edit /:id:使用createemployee组件编辑现有员工记录

One last thing is to the define navigation menu for our application. In “/app/components/navmenu/”, open navmenu.component.html and insert the following code.

最后一件事是为我们的应用程序定义导航菜单。 在“ / app / components / navmenu /”中,打开navmenu.component.html并插入以下代码。

<div class='main-nav'>      <div class='navbar navbar-inverse'>          <div class='navbar-header'>              <button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>                  <span class='sr-only'>Toggle navigation</span>                  <span class='icon-bar'></span>                  <span class='icon-bar'></span>                  <span class='icon-bar'></span>              </button>              <a class='navbar-brand' [routerLink]="['/home']">ASPCoreWithAngular</a>          </div>          <div class='clearfix'></div>          <div class='navbar-collapse collapse'>              <ul class='nav navbar-nav'>                  <li [routerLinkActive]="['link-active']">                      <a [routerLink]="['/home']">                          <span class='glyphicon glyphicon-home'></span> Home                      </a>                  </li>                  <li [routerLinkActive]="['link-active']">                      <a [routerLink]="['/fetch-employee']">                          <span class='glyphicon glyphicon-th-list'></span> Fetch employee                      </a>                  </li>              </ul>          </div>      </div>  </div>

And that’s it. We have created our first ASP.NET Core application using Angular 5 and Entity Framework core database first approach.

就是这样。 我们已经使用Angular 5和Entity Framework核心数据库优先方法创建了第一个ASP.NET Core应用程序。

执行演示 (Execution Demo)

Press F5 to launch the application.

按F5启动应用程序。

A web page will open as shown in the image below. Notice the URL showing the route for our home component. The navigation menu on the left shows the navigation link for the “Home” and “Fetch Employee” pages.

如下图所示,将打开一个网页。 请注意显示我们home组件路线的URL。 左侧的导航菜单显示“主页”和“提取员工”页面的导航链接。

Click on “Fetch Employee” in the navigation menu. It will redirect to the fetchemployee component, and displays all the employee data on the page.

在导航菜单中单击“提取员工”。 它将重定向到fetchemployee组件,并在页面上显示所有员工数据。

Since we have not added any data it is empty.

由于我们尚未添加任何数据,因此为空。

Click on “Create New to navigate to the “/register-employeepage. Add a new Employee record as shown in the image below. You can see that the City field is a dropdown list, containing all the city names that we inserted into tblCities.

单击“新建以导航到“ / register-employee 页面。 如下图所示添加新的Employee记录。 您会看到City字段是一个下拉列表,其中包含我们插入到tblCities中的所有城市名称。

If we miss the data in any field while creating an employee record, we will get a required field validation error message

如果在创建员工记录时错过任何字段中的数据,我们将收到必填字段验证错误消息

After inserting the data in all the fields, click on the “Save” button. The new employee record will be created, and you will be redirected to the “/fetch-employeepage. This page displays the records of all the employees. Here, we can also see action methods “Edit” and “Delete”.

在所有字段中插入数据后,单击“保存”按钮。 新的员工记录将被创建,您将被重定向到“ / fetch-employee 页面。 此页面显示所有员工的记录。 在这里,我们还可以看到操作方法“编辑”和“删除”。

If we want to edit an existing employee record, click the “Edit” action link. It will open the “Edit” page as below, where we can change the employee data. Notice that we have passed the EmployeeId in the URL parameter.

如果我们要编辑现有员工记录,请单击“编辑”操作链接。 它将如下所示打开“编辑”页面,我们可以在其中更改员工数据。 请注意,我们已经在URL参数中传递了EmployeeId。

Here we have changed the City of employee Rahul from Hyderabad to Chennai. Click on “Save” to return to the “fetch-employee” page to see the updated changes as highlighted in the image below.

在这里,我们已将员工拉胡尔City从海得拉巴更改为金奈。 单击“保存”返回到“提取雇员”页面,以查看更新的更改,如下图所示。

If we miss any fields while editing the employee records, then Edit view will also throw a required field validation error message as shown in the image below:

如果在编辑员工记录时错过任何字段,那么“编辑”视图还将抛出必填字段验证错误消息,如下图所示:

Now, we will perform a “Delete” operation on an employee named Swati with Employee Id 2. Click on the “Delete” action link. This will open a JavaScript confirmation box asking for a confirmation to delete.

现在,我们将使用员工ID 2对名为Swati的员工执行“删除”操作。单击“删除”操作链接。 这将打开一个JavaScript确认框,要求您删除确认。

Once we click on “OK”, the Swati who is Employee Id 2 will be removed from our record. You can see the updated list of employees as shown below.

一旦我们单击“确定”,员工ID 2的Swati将从我们的记录中删除。 您可以看到更新的员工列表,如下所示。

其他有用的来源: (Other useful sources:)

结论 (Conclusion)

We have successfully created an ASP.NET Core application using Angular 5 and Entity Framework core database first approach with the help of Visual Studio 2017 and SQL Server 2012. We have used Angular forms to get data from the user and also bind the dropdown list to the database table using Entity framework.

我们已在Visual Studio 2017和SQL Server 2012的帮助下使用Angular 5和Entity Framework核心数据库优先方法成功创建了ASP.NET Core应用程序。我们已使用Angular表单从用户获取数据,并将下拉列表绑定到使用实体框架的数据库表。

You can check out my other articles on ASP .NET Core here.

您可以在此处查看有关ASP.NET Core的其他文章。

Originally published at https://ankitsharmablogs.com/

最初发布在https://ankitsharmablogs.com/

翻译自: https://www.freecodecamp.org/news/asp-net-core-crud-using-angular-5-and-entity-framework-core-374ac04cd3ec/

angular 部署

 类似资料: