angular 部署
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.0和Angular 5创建一个Web应用程序。 我们将创建一个示例员工记录管理系统。 为了从用户那里读取输入,我们将在客户端使用Angular表单以及必需的字段验证。 我们还将使用EF Core将Angular形式的下拉列表绑定到数据库中的表。
We will be using Visual Studio 2017 and SQL Server version 2008 or above.
我们将使用Visual Studio 2017和SQL Server 2008或更高版本。
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。
Before proceeding, I recommend you get the source code from Github.
在继续之前,建议您从Github获取源代码。
We will be using two tables to store our data.
我们将使用两个表来存储我们的数据。
tblEmployee
: used to store the details of employees. It contains fields such as EmployeeID, Name, City, Department, and Gender.
tblEmployee
:用于存储员工的详细信息。 它包含诸如EmployeeID,姓名,城市,部门和性别之类的字段。
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应用程序。
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”文件夹。
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 EmployeeDataAccessLa
yer.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控制器。
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编写前端代码。
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.serv
ice.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.
现在,我们将创建我们的组件。
We will be adding two Angular components to our application:
我们将在我们的应用程序中添加两个Angular组件:
fetchemployee
component: to display all the employee data or delete existing employee data.
fetchemployee
组件:显示所有员工数据或删除现有员工数据。
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.ts
和fetchemployee.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
内部 我们正在调用服务EmployeeService
的getEmployees
方法的方法。 这将返回一个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
内部,我们执行两个操作:
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
将在页面加载时填充下拉列表。
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
。
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 fetchemployee
component
fetch-employee:使用fetchemployee
组件显示所有员工数据
register-employee: to add new employee record using the createemployee
component
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应用程序。
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-employee” page. 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-employee” page. 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将从我们的记录中删除。 您可以看到更新的员工列表,如下所示。
CRUD Operations With ASP.NET Core Using Angular 5 and ADO.NET
CRUD Operation With ASP.NET Core MVC Using Visual Studio Code and EF
CRUD Operation With ASP.NET Core MVC Using ADO.NET and Visual Studio 2017
CRUD Operation With ASP.NET Core MVC using Visual Studio Code and ADO.NET
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/
angular 部署