Merge pull request #8803 from abpframework/auto-merge/rel-4-3/353

pull/8809/head
maliming 5 years ago committed by GitHub
commit 8f0ade002a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -428,7 +428,7 @@ Open the `Index.cshtml` file in the `Pages` folder of the *TodoApp.Web* project
</div>
````
We are using ABP's [card tag helper](../../UI/AspNetCore/Tag-Helpers/Cards.md) to create a simple card view. You could directly use the standard bootstrap HTML structure, however the ABP [tag helpers]() make it much easier and type safe.
We are using ABP's [card tag helper](../../UI/AspNetCore/Tag-Helpers/Cards.md) to create a simple card view. You could directly use the standard bootstrap HTML structure, however the ABP [tag helpers](../../UI/AspNetCore/Tag-Helpers/Index.md) make it much easier and type safe.
This page imports a CSS and a JavaScript file, so we should also create them.

@ -8,11 +8,12 @@
}
````
这是一个单独的部分,使用ABP框架构建简单todo应用程序的快速入门教程.这是一个最终应用的截图:
这是一个单独的部分,使用ABP框架构建简单待办事项应用程序的快速入门教程.这是一个最终应用的截图:
![todo-list](todo-list.png)
你可以从已完成的项目里找到源代码,[这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp).
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp)找到已完成的项目源代码.
## 先决条件
* 一个集成开发环境 (比如: [Visual Studio](https://visualstudio.microsoft.com/vs/)) 它需要支持 [.NET 5.0+](https://dotnet.microsoft.com/download/dotnet) 的开发.
@ -117,10 +118,10 @@ npm start
一切就绪.我们可以开始编码了!
## Domain Layer 领域层
## 领域层
此应用程序只有一个 [实体](../../Entities.md) 我们开始创建它. 在*TodoApp.Domain*项目中创建一个新的 `TodoItem` 类:
此应用程序只有一个 [entity](../../Entities.md) and we are starting by creating it. Create a new `TodoItem` class inside the *TodoApp.Domain* project:
我们开始创建它. 在*TodoApp.Domain*项目中创建一个新的 `TodoItem` 类:
````csharp
using System;
using Volo.Abp.Domain.Entities;
@ -135,11 +136,12 @@ namespace TodoApp
````
`BasicAggregateRoot` 是创建根实体的最简单的基类之一,`Guid` 是这里实体的主键 (`Id`).
## Database Integration 数据库集成
{{if DB=="EF"}}
下一步是置 [Entity Framework Core](../../Entity-Framework-Core.md) 配置.
下一步是置 [Entity Framework Core](../../Entity-Framework-Core.md).
### Mapping Configuration 映射配置
@ -165,7 +167,7 @@ public static void ConfigureTodoApp(this ModelBuilder builder)
我们已经将 `TodoItem` 实体映射到数据库中的 `TodoItems` 表.
### Code First Migrations 代码优先迁移
### 代码优先迁移
解决方案启动模版已经配置为使用Entity Framework Core [Code First 迁移](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations).由于我们已经更改了数据库映射配置,因此我们应该创建一个新的迁移并将更改应用于数据库.
@ -189,6 +191,7 @@ dotnet ef database update
{{else if DB=="Mongo"}}
下一步是设置 [MongoDB](../MongoDB.md) 配置.在 *TodoApp.MongoDB* 项目的 `MongoDb` 文件夹中打开 `TodoAppMongoDbContext` 类,并进行以下更改;
1. 向类添加新属性:
````csharp
@ -206,17 +209,17 @@ modelBuilder.Entity<TodoItem>(b =>
{{end}}
现在,我们可以使用ABP仓储来保存和检索todo列表项了,就像我们将在下一节中做的那样.
现在,我们可以使用ABP仓储来保存和检索待办事项列表项了,就像我们将在下一节中做的那样.
## Application Layer 应用层
## 应用层
[Application Service应用服务](../../Application-Services.md) 用于执行应用程序的用例.我们需要执行以下用例;
[应用服务](../../Application-Services.md) 用于执行应用程序的用例.我们需要执行以下用例;
* 获取待办事项列表
* 创建新的todo
* 删除现有的todo项目
* 创建新的待办事
* 删除现有的待办事项
### Application Service Interface 应用服务接口
### 应用服务接口
我们可以从为应用程序服务定义一个接口开始.在 *TodoApp.Application.Contracts* 项目中创建一个新的 `ITodoAppService` 接口,如下所示:
@ -237,9 +240,9 @@ namespace TodoApp
}
````
### Data Transfer Object 数据传输对象
### 数据传输对象
`GetListAsync` and `CreateAsync` methods return `TodoItemDto`. Applications Services typically gets and returns DTOs ([Data Transfer Objects](../../Data-Transfer-Objects.md)) instead of entities. So, we should define the DTO class here. Create a new `TodoItemDto` class inside the *TodoApp.Application.Contracts* project:
`GetListAsync` `CreateAsync` 方法返回 `TodoItemDto`. 通常应用服务获取或返回的是 DTO ([数据传输对象](../../Data-Transfer-Objects.md)) 而不是直接获取或返回实体对象. 所以,我们应该在此定义 DTO(数据传输对象) 类. 在 *TodoApp.Application.Contracts* 项目中创建一个名为 `TodoItemDto` 的类:
````csharp
using System;
@ -254,9 +257,9 @@ namespace TodoApp
}
````
这是一个非常简单的DTO类,与我们的 `TodoItem` 实体匹配.我们接下来实现 `ITodoAppService` 接口.
这是一个非常简单的DTO类,与我们的 `TodoItem` 实体相对应.我们接下来实现 `ITodoAppService` 接口.
### Application Service Implementation 应用服务实现
### 应用服务实现
*TodoApp.Application* 项目内部创建一个 `TodoAppService` 类,如下所示:
@ -284,11 +287,11 @@ namespace TodoApp
}
````
该类继承自ABP框架的 `ApplicationService` 类,并实现之前定义的 `ITodoAppService`接口.ABP为实体提供默认的通用 [repositories存储库](../repositories.md).我们可以使用它们来执行基本的数据库操作.此类 [injects 注入](../Dependency-Injection.md) `IRepository<TodoItem, Guid>``TodoItem` 实体的默认存储库.我们将使用它来实现之前描述的用例.
该类继承自ABP框架的 `ApplicationService` 类,并实现之前定义的 `ITodoAppService`接口.ABP为实体提供默认的通用的 [仓储](../repositories.md).我们可以使用它们来执行基本的数据库操作. 这个类 [注入](../Dependency-Injection.md) `IRepository<TodoItem, Guid>` `TodoItem` 实体的默认存储库.我们将使用它来实现之前描述的用例.
#### 获取所有Todo项列表
#### 获取所有待办事项列表
Let's start by implementing the `GetListAsync` method:
让我们开始实现 `GetListAsync` 方法:
````csharp
public async Task<List<TodoItemDto>> GetListAsync()
@ -305,7 +308,7 @@ public async Task<List<TodoItemDto>> GetListAsync()
我们只是简单的从数据库中获取完整的 `TodoItem` 列表,将它们映射到 `TodoItemDto` 对象并作为结果返回.
#### 创建一个新的Todo
#### 创建一个新的待办事
下一个方法是 `CreateAsync`,我们可以像如下所示来实现:
@ -324,9 +327,9 @@ public async Task<TodoItemDto> CreateAsync(string text)
}
````
Repository`InsertAsync` 方法将给定的 `TodoItem` 插入数据库,并返回相同的 `TodoItem` 对象.它还设置 `Id`,因此我们可以在返回对象上使用它.我们只是通过从新的 `TodoItem` 实体创建返回 `TodoItemDto`.
仓储`InsertAsync` 方法将给定的 `TodoItem` 插入数据库,并返回相同的 `TodoItem` 对象.它还设置 `Id`,因此我们可以在返回对象上使用它.我们只是通过从新的 `TodoItem` 实体创建返回 `TodoItemDto`.
#### 删除一个子
#### 删除待办事
最后,我们可以将 `DeleteAsync` 实现为以下代码块:
@ -337,9 +340,9 @@ public async Task DeleteAsync(Guid id)
}
````
应用程序服务已准备好从UI层使用.
至此应用程序服务已准备好了让UI层来使用.
## User Interface Layer 用户界面层
## 用户界面层
是时候在UI上显示待办事项了!在开始编写代码之前,最好记住我们正在尝试构建的内容.这是最终UI的示例屏幕截图:
@ -378,7 +381,7 @@ namespace TodoApp.Web.Pages
}
````
此类使用 `ITodoAppService` 获取todo项目列表并分配 `TodoItems` 属性.我们将用它来渲染razor页面上的待办事项.
此类使用 `ITodoAppService` 获取待办事项目列表并将它赋值给 `TodoItems` 属性.我们将用它来渲染razor页面上的待办事项目列表.
### Index.cshtml
@ -424,7 +427,7 @@ namespace TodoApp.Web.Pages
</div>
````
我们使用ABP的 [card tag helper 卡片标签助手](../UI/AspNetCore/标签助手/Cards.md) 创建一个简单的卡片视图.你可以直接使用标准的bootstrap HTML,不过ABP的 [tag helpers 标签助手]() 使它更容易并且类型安全.
我们使用ABP的 [卡片标签助手](../../UI/AspNetCore/Tag-Helpers/Cards.md) 创建一个简单的卡片视图.你可以直接使用标准的bootstrap HTML, 不过ABP的[标签助手](../../UI/AspNetCore/Tag-Helpers/Index.md) 使它更简单并且类型安全.
这个页面要导入一个CSS和一个JavaScript文件,所以我们也应该创建它们.
@ -461,15 +464,15 @@ $(function () {
});
````
在第一部分中,我们在todo项目附近注册点击垃圾图标的事件,删除服务器上的相关项目并在UI上显示通知.另外,我们从DOM中删除已删除的项,因此我们不需要刷新页面.
在第一部分中,我们在待办事项目附近注册点击删除图标所要触发的事件,删除服务器上的相关待办事项并在UI上显示通知.另外,我们从DOM中删除已删除的项,因此我们不需要刷新页面.
在第二部分中,我们在服务器上创建一个新的todo事项.如果成功,我们将操纵DOM以将新的 `<li>` 元素插入todo列表.这样,创建新的todo条目后就不用刷新整个页面了.
在第二部分中,我们在服务器上创建一个新的待办事项.如果成功,我们将操纵DOM以将新的 `<li>` 元素插入todo列表.这样,创建新的待办事项后就不用刷新整个页面了.
这里有趣的部分是我们如何与服务器通信.请参阅 *Dynamic JavaScript Proxies & Auto API Controllers 动态JavaScript代理和自动API控制器* 部分,以了解其工作原理.但是现在让我们继续并完成申请.
这里有趣的部分是我们如何与服务器通信.请参阅 *动态JavaScript代理和自动API控制器* 部分,以了解其工作原理.但是现在让我们继续并完成这个应用程序.
### Index.css
最后要做的,请打开 *TodoApp.Web* 项目的 `Pages` 文件夹中的 `Index.css` 文件,并替换为以下内容:
来到最后要做的工作,请打开 *TodoApp.Web* 项目的 `Pages` 文件夹中的 `Index.css` 文件,并替换为以下内容:
````css
#TodoList{
@ -498,15 +501,15 @@ $(function () {
}
````
这是todo页面的简单样式.我们相信你可以做得更好 :)
这是待办事项页面的简单样式.我们相信你可以做得更好 :)
现在,你可以再次运行应用程序以查看结果.
### Dynamic JavaScript Proxies & Auto API Controllers 动态JavaScript代理和自动应用编程接口控制器
`Index.js` 文件中,我们使用了 `todoApp.todo.delete(...)``todoApp.todo.create(...)` 函数与服务器通信.这些函数是由ABP框架动态创建的,这要归功于 [Dynamic JavaScript Client Proxy 动态JavaScript客户端代理](../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) 系统.他们对服务器执行HTTP API调用并返回承诺,因此你可以像上面所做的那样注册对 `then` 函数的回调.
`Index.js` 文件中,我们使用了 `todoApp.todo.delete(...)``todoApp.todo.create(...)` 函数与服务器通信.这些函数是由ABP框架动态创建的,这要归功于 [动态JavaScript客户端代理](../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) 系统.他们对服务器执行HTTP API调用并返回承诺,因此你可以像上面所做的那样注册对 `then` 函数的回调.
但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求这个问题给我们带来了ABP框架的 [Auto API Controller 自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API Controllers(API控制器).
但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求呢? 这个问题为我们引出了ABP框架的 [自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API Controllers(API控制器).
如果通过在应用程序中输入 `/swagger` URL来打开 [swagger UI](https://swagger.io/tools/ Swagger-ui/),则可以看到Todo API:
@ -555,11 +558,11 @@ namespace TodoApp.Blazor.Pages
}
````
这个类使用 `ITodoAppService`todo项执行操作.它在创建和删除操作后操纵 `TodoItems` 列表.这样,我们不需要从服务器刷新整个todo列表.
这个类使用 `ITodoAppService`待办事项执行操作.它在创建和删除操作后操纵 `TodoItems` 列表.这样,我们不需要从服务器刷新整个todo列表.
{{if UI=="Blazor"}}
请参阅下面的 *Dynamic C# Proxies & Auto API Controllers 动态C # 代理和自动API控制器* 部分,了解如何从浏览器上运行的Blazor应用程序注入和使用应用程序服务接口!但是现在,让我们继续并完成这个应用.
请参阅下面的 *动态C # 代理和自动API控制器* 部分,了解如何从浏览器上运行的Blazor应用程序注入和使用应用程序服务接口!但是现在,让我们继续并完成这个应用.
{{end # Blazor}}
@ -637,7 +640,7 @@ namespace TodoApp.Blazor.Pages
}
````
这是todo页面的简单样式.我们相信你可以做得更好 :)
这是待办事项页面的简单样式.我们相信你可以做得更好 :)
现在,你可以再次运行应用程序以查看结果.
@ -645,11 +648,11 @@ namespace TodoApp.Blazor.Pages
### Dynamic C# Proxies & Auto API Controllers 动态C#代理和自动应用编程接口控制器
`Index.razor.cs` 文件中,我们已经注入 (使用 `[Inject]` 特性),并像使用本地服务一样使用 `ITodoAppService`.请记住,当此应用程序服务的实现在服务器上运行时,Blazor应用程序正在浏览器上运行.
`Index.razor.cs` 文件中,我们已经注入(使用 `[Inject]` 特性)并像使用本地服务一样使用 `ITodoAppService`.请记住,当此应用程序服务的实例在服务器上运行的同时,Blazor应用程序正在浏览器上运行.
这个神奇的过程是由ABP框架的 [Dynamic C# Client Proxy 动态C#客户端代理](../API/Dynamic-CSharp-API-Clients.md) 系统完成的.它使用标准的 `HttpClient` 并向远程服务器执行HTTP API请求.它还为我们处理所有标准任务,包括授权,JSON序列化和异常处理.
这个神奇的过程是由ABP框架的 [动态C#客户端代理](../API/Dynamic-CSharp-API-Clients.md) 系统完成的.它使用标准的 `HttpClient` 并向远程服务器执行HTTP API请求.它还为我们处理所有标准任务,包括授权,JSON序列化和异常处理.
但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求这个问题给我们带来了ABP框架的 [Auto API Controller 自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API控制器.
但是,你可能会问我们还没有创建任何API控制器,那么服务器如何处理这些请求呢? 这个问题为我们引出了ABP框架的 [自动API控制器](../API/Auto-API-Controllers.md) 功能.它通过约定自动将应用程序服务转换为API控制器.
如果你运行 `TodoApp.HttpApi.Host` 应用程序,你可以看到Todo API:
@ -659,7 +662,7 @@ namespace TodoApp.Blazor.Pages
{{else if UI=="NG"}}
### Service Proxy Generation 服务代理生成
### 服务代理生成
ABP提供了一个方便的功能,可以自动创建客户端服务,轻松使用服务器提供的HTTP APIs.
@ -733,7 +736,7 @@ export class HomeComponent implements OnInit {
````
我们已经使用 `todoService` 来获取todo项目的列表,并将返回值分配`todoItems` 数组.我们还添加了 `create``delete` 方法.这些方法将在视图端使用.
我们已经实现了使用 `todoService` 来获取待办事项目列表,并将返回值赋值`todoItems` 数组.我们还添加了 `create``delete` 方法.这些方法将在视图端使用.
### home.component.html
@ -800,7 +803,7 @@ export class HomeComponent implements OnInit {
}
````
这是todo页面的简单样式.我们相信你可以做得更好 :)
这是待办事项页面的简单样式.我们相信你可以做得更好 :)
现在,你可以再次运行应用程序以查看结果.
@ -808,11 +811,11 @@ export class HomeComponent implements OnInit {
## 总结
在本教程中,我们构建了一个非常简单的应用程序来抢先探究ABP框架的新特性.如果你想构建一个实的应用程序,请查看 [应用程序开发教程](../Part-1.md),其中涵盖了实际web应用程序开发的所有方面.
在本教程中,我们构建了一个非常简单的应用程序来抢先探究ABP框架的新特性.如果你想构建一个实际场景的应用程序,请查看 [应用程序开发教程](../Part-1.md),其中涵盖了实际web应用程序开发的所有方面.
## 源代码
你可以找到完成的应用程序的源代码 [这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp).
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/TodoApp)获取到完整的应用程序源代码.
## 另请参见

@ -526,7 +526,7 @@ namespace Volo.Abp.Cli.ProjectModification
{
foreach (var npmPackage in mvcNpmPackages)
{
await ProjectNpmPackageAdder.AddMvcPackageAsync(Path.GetDirectoryName(targetProject), npmPackage, null, true);
await ProjectNpmPackageAdder.AddMvcPackageAsync(Path.GetDirectoryName(targetProject), npmPackage);
}
}
}

Loading…
Cancel
Save